1. SSR与CSR的区别
1.1. SSR的原理
服务端渲染(SSR)是在服务器端将 Vue 组件渲染为 HTML 字符串,并将其发送给客户端。这种方式与客户端渲染(CSR)不同,后者是在浏览器中执行 JavaScript 来生成 HTML。
在 SSR 中,客户端第一次访问页面时,服务器会根据请求路径渲染对应的 HTML 页面,这有利于提升首屏加载速度和 SEO 性能。之后,客户端还需要进行“激活”,通过 Vue 的 hydrate 方法让已经渲染好的 HTML 具备动态交互能力。而 CSR 则是先加载静态 HTML 框架,之后由客户端完成所有页面的 JavaScript 渲染。
1.2. 两者的主要区别
SEO:SSR 在服务器端生成完整的 HTML,利于搜索引擎爬取,而 CSR 生成的 HTML 需要等到 JavaScript 执行完毕后才可用。
性能:SSR 的首屏渲染速度快,但会增加服务器负载;CSR 依赖浏览器的计算能力,但可以降低服务器的压力。
安全:SSR 可以更好地控制输出内容,减少 XSS 攻击的风险。
2. SSR 中如何解决首屏数据获取问题
在 Vue SSR 中,首屏数据的获取需要提前在服务器端完成。常用的解决方案是在组件中定义一个 asyncData 方法,专门用于数据预取。这个方法在组件渲染之前调用,服务器端会在渲染 HTML 之前获取数据并将其注入到组件的 props 中。
2.1. 具体步骤
1. 在服务器端,在 SSR 渲染函数中,先调用组件的 asyncData 方法获取数据,再将数据注入到 Vue 组件的 props。
2. 在客户端,Vue 会利用 hydrate 方法进行激活,接管服务器端生成的 HTML。客户端还会将服务器预取的数据作为初始状态传递,避免重复请求。
数据预取的关键在于服务器端需要等待数据加载完毕再渲染页面,以保证返回给客户端的 HTML 包含实际的数据。
// 组件中定义 asyncData 方法
export default {async asyncData({ app }) {const data = await fetchData();return { data };},render(h) {return h('div', this.data);}
};
3. 处理路由和状态同步问题
在 Vue SSR 中,路由和状态的同步非常重要。为了确保服务器和客户端渲染结果一致,必须在服务器端渲染时同步路由和状态。常用的做法包括:
3.1. 路由同步
在服务器端渲染时,服务器会根据用户的请求 URL 手动调用 router.push() 将路由切换到正确的页面,然后等待 router.isReady() 确保所有异步路由组件加载完毕后,再进行服务器端渲染。客户端同样会根据当前 URL 初始化路由。
// 服务器端路由同步
app.use((req, res, next) => {router.push(req.path, (err, url) => {if (err) {res.status(404).end();} else {app.context.url = url;next();}});
});
3.2. 状态同步
在 SSR 场景中,服务器端渲染后的状态(如 Pinia 的 store 状态)需要传递到客户端。这通常是通过将状态序列化并嵌入到 HTML 中,客户端在激活时会使用这些初始状态,避免再次请求数据。
// 状态同步
const store = createPinia();
const app = createApp({store,render: () => h(App)
});app.mount('#app', () => {const state = store.state.value;document.getElementById('state').textContent = JSON.stringify(state);
});
4. 总结
Vue 3 的服务端渲染(SSR)和客户端渲染(CSR)各有优缺点。SSR 提升了首屏加载速度和 SEO 性能,但增加了服务器负载;CSR 则依赖浏览器的计算能力,降低了服务器压力。在实际应用中,开发者需要根据项目需求选择合适的渲染方式,并采取相应的解决方案来处理首屏数据获取和路由及状态同步问题,以确保应用的性能和用户体验。