vue实现最佳ssr
Vue SSR 实现方案
Vue.js 的服务器端渲染(SSR)能提升首屏加载速度和 SEO 优化。以下是实现 Vue SSR 的最佳实践方案:
基础架构搭建
使用官方推荐的 vue-server-renderer 和 webpack 构建 SSR 应用。核心依赖包括:
npm install vue vue-server-renderer express webpack-node-externals
创建基础服务端入口文件:
// server.js
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
const app = new Vue({
data: { url: req.url },
template: `<div>访问的URL是:{{ url }}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(html)
})
})
server.listen(8080)
通用代码结构
采用同构应用结构,共享客户端和服务端代码:
src/
├── components/
├── App.vue
├── app.js # 通用入口
├── entry-client.js # 客户端入口
└── entry-server.js # 服务端入口
服务端入口示例:
// entry-server.js
import { createApp } from './app'
export default context => {
return new Promise((resolve, reject) => {
const { app, router } = createApp()
router.push(context.url)
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
if (!matchedComponents.length) {
return reject({ code: 404 })
}
resolve(app)
}, reject)
})
}
数据预取与状态同步
使用 Vuex 进行状态管理并实现数据预取:
// store.js
export function createStore() {
return new Vuex.Store({
state: {
items: []
},
actions: {
fetchItems({ commit }) {
return api.fetchItems().then(items => {
commit('setItems', items)
})
}
},
mutations: {
setItems(state, items) {
state.items = items
}
}
})
}
组件内数据预取:
export default {
asyncData({ store }) {
return store.dispatch('fetchItems')
}
}
客户端激活与混合
确保客户端能正确接管服务端渲染的静态标记:
// entry-client.js
import { createApp } from './app'
const { app, router, store } = createApp()
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__)
}
router.onReady(() => {
app.$mount('#app')
})
构建配置优化
分别配置客户端和服务端 webpack 构建:
// webpack.server.config.js
const nodeExternals = require('webpack-node-externals')
module.exports = {
target: 'node',
externals: [nodeExternals()],
output: {
libraryTarget: 'commonjs2'
}
}
性能优化措施
实现以下优化策略提升 SSR 性能:
- 使用
lru-cache实现组件级缓存 - 启用
shouldPrefetch控制资源预加载 - 配置
bundleRenderer的runInNewContext为 false - 实现流式渲染减少 TTFB 时间
示例缓存配置:
const LRU = require('lru-cache')
const renderer = createBundleRenderer(serverBundle, {
cache: LRU({
max: 1000,
maxAge: 1000 * 60 * 15
})
})
生产环境部署
推荐使用 PM2 集群模式部署:
pm2 start server.js -i max
配置 Nginx 作为反向代理:
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
监控与错误处理
实现全面的错误捕获机制:
// 全局错误处理
renderer.renderToString(context, (err, html) => {
if (err) {
if (err.code === 404) {
res.status(404).end('Page not found')
} else {
res.status(500).end('Internal Server Error')
}
} else {
res.end(html)
}
})
Nuxt.js 替代方案
对于快速实现 SSR,可以考虑使用 Nuxt.js 框架:
npx create-nuxt-app my-ssr-app
Nuxt 提供开箱即用的 SSR 支持,包含以下特性:

- 自动路由生成
- 内置 Vuex 状态树
- 异步数据获取
- 静态文件服务
- 自动代码分割






