SSR 数据预取策略
数据预取在服务端渲染前获取数据,注入到 HTML 中供客户端使用。
数据预取流程
JavaScript
请求到达 → 服务端预取数据 → 渲染 HTML → 注入数据 → 返回页面
客户端加载 → 读取注入数据 → 状态同步 → 渲染完成
Vue 数据预取
HTML
// 服务端入口
export async function render(url) {
const app = createSSRApp(App)
const pinia = createPinia()
app.use(pinia)
// 预取数据
const store = useStore(pinia)
await store.fetchData(url)
// 渲染 HTML
const html = await renderToString(app)
// 注入状态
const state = JSON.stringify(pinia.state.value)
return {
html,
state
}
}
数据注入 HTML
JavaScript
<script>
window.__INITIAL_STATE__ = ${state}
</script>
客户端读取:
vue
// 客户端入口
const pinia = createPinia()
// 同步服务端状态
if (window.__INITIAL_STATE__) {
pinia.state.value = window.__INITIAL_STATE__
}
app.use(pinia)
注意:数据注入确保客户端无需再次请求相同数据。
数据预取时机
| 钩子 | 说明 | |
|---|---|---|
| serverPrefetch | Vue 组件预取 | |
| asyncData | Nuxt 页面预取 | |
| setup | 组件初始化 |
Nuxt asyncData
JavaScript
<script setup>
// Nuxt 数据预取
const { data } = await useFetch('/api/data')
</script>
预取优化策略
| 策略 | 说明 | |
|---|---|---|
| 并行预取 | 多个请求并行执行 | |
| 缓存数据 | 预取结果缓存 | |
| 条件预取 | 按路由条件预取 | |
| 增量预取 | 用户交互时补充 |
并行数据预取
JavaScript
// 并行预取多个数据源
async function prefetchAll() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
])
return { user, posts, comments }
}
数据大小控制
text
// 控制注入数据大小
const MAX_STATE_SIZE = 100 * 1024 // 100KB
if (JSON.stringify(state).length > MAX_STATE_SIZE) {
// 过大数据不注入
// 客户端按需请求
}
要点总结
- 服务端预取数据注入 HTML
- 客户端读取 window.INITIAL_STATE 同步
- 使用 serverPrefetch 或 asyncData
- 并行预取提升效率
📝 发现内容有误?点击此处直接编辑