1. 核心概念
-
定义:SSR 在服务器端执行前端框架(如React、Vue)的代码,生成包含动态内容的HTML页面,客户端接收后直接展示,再通过“注水”(Hydration)绑定交互逻辑。
-
对比:
-
客户端渲染(CSR):浏览器下载空HTML后,通过JavaScript动态渲染内容,首屏加载慢,SEO不友好。
-
静态生成(SSG):构建时生成静态HTML,适用于内容固定的场景(如博客),而SSR每次请求动态生成。
-
2. 核心流程
服务器处理请求:收到请求后,服务器执行应用代码(如React组件)。
数据获取:在服务器端获取页面所需数据(如API调用)。
生成HTML:将数据注入组件,渲染为完整HTML。
返回客户端:发送HTML、CSS和客户端JavaScript。
客户端激活(Hydration):JavaScript加载后,将静态HTML转换为可交互页面。
3. 优势
-
更快的首屏加载:用户立即看到内容,无需等待JS执行。
-
SEO友好:搜索引擎爬虫直接解析HTML中的内容。
-
低端设备兼容性:减少客户端计算压力。
4. 挑战与缺点
-
服务器负载:每次请求需渲染页面,增加服务器压力。
-
开发复杂度:需处理服务端与客户端环境差异(如window对象不可用)。
-
注水失败风险:服务器与客户端渲染的DOM不一致会导致错误。
-
TTI延迟:虽然首屏快,但可交互时间可能因JS加载而延迟。
5. 常用框架
-
React:Next.js
-
Vue:Nuxt.js
-
Angular:Angular Universal
-
通用工具:SvelteKit、Gatsby(SSG为主)
6. 实现注意事项
-
数据获取:在服务器端使用API(如Next.js的getServerSideProps)预取数据。
-
代码同构(Isomorphic):确保组件代码在服务端和客户端均可运行。
-
环境适配:避免直接操作DOM,使用useEffect或生命周期钩子区分环境。
-
缓存策略:对频繁请求的页面进行缓存,减轻服务器压力。
-
错误处理:服务器端渲染失败时需优雅降级(如回退到CSR)。
7. 优化策略
-
流式渲染:分块传输HTML,提升首字节时间(如React的renderToNodeStream)。
-
部分SSR:仅对关键页面使用SSR,其他用CSR或SSG。
-
CDN缓存:结合CDN缓存静态资源或页面片段。
-
按需加载:客户端按需加载非关键JS代码。
8. 适用场景
-
内容密集型网站:新闻、博客、电商产品页(需SEO)。
-
动态数据页面:用户仪表盘(需实时数据但首屏要求高)。
-
兼顾性能与SEO的应用:如企业官网、营销页面。
9. 安全考虑
-
XSS防护:服务器渲染时需对动态内容转义(如React自动转义dangerouslySetInnerHTML)。
-
避免敏感数据泄露:确保服务器端不暴露用户隐私数据。
一、Vue 项目实现 SSR(以 Nuxt.js 为例)
Nuxt.js 是 Vue 生态中专门为 SSR 设计的框架,开箱即用。
1. 创建 Nuxt 项目
npx create-nuxt-app my-ssr-app
# 选择SSR模式(Universal模式)
2. 目录结构
Nuxt 自动生成约定式路由和页面:
pages/
index.vue # 对应路由 /
about.vue # 对应路由 /about
3. 页面组件与数据获取
在页面组件中使用 asyncData 或 fetch 方法在服务器端获取数据:
写博客的时候这里没有找到vue后缀的代码区块。
<!– pages/index.vue –>
<template>
<div>
<h1>{{ title }}</h1>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData({ $axios }) {
// 服务器端获取数据(仅在首次加载时执行)
const posts = await $axios.get('https://api.example.com/posts');
return {
title: 'Server-Side Rendered Posts',
posts: posts.data
};
}
}
</script>
4. 部署与运行
-
开发模式:
npm run dev
-
生产构建:
npm run build
npm run start
5. 关键配置
-
nuxt.config.js:配置插件、中间件、构建选项等。
-
使用 @nuxtjs/axios 模块简化 API 请求。
二、React 项目实现 SSR(以 Next.js 为例)
Next.js 是 React 生态中支持 SSR 的主流框架。
1. 创建 Next 项目
npx create-next-app my-ssr-app
2. 目录结构
pages/
index.js # 对应路由 /
about.js # 对应路由 /about
3. 页面组件与数据获取
使用 getServerSideProps 在服务器端获取数据:
写博客的时候这里没有找到jsx后缀的代码区块。
// pages/index.js
export default function HomePage({ posts }) {
return (
<div>
<h1>Server-Side Rendered Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
// 服务器端数据获取(每次请求时执行)
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: { posts }
};
}
4. 部署与运行
-
开发模式:
npm run dev
-
生产构建:
npm run build
npm run start
5. 关键配置
-
next.config.js:自定义 Webpack、路由、环境变量等。
-
使用 next/router 处理客户端路由。
三、Vue vs React 的 SSR 实现对比
数据获取方法 | asyncData、fetch | getServerSideProps、getStaticProps |
路由 | 自动基于 pages/ 目录生成 | 自动基于 pages/ 目录生成 |
客户端激活(Hydration) | 自动处理 Vue 实例与 SSR 内容的绑定 | 自动处理 React 组件与 SSR 内容的绑定 |
静态生成支持 | 支持(nuxt generate) | 支持(getStaticProps + npm run export) |
学习曲线 | 对 Vue 开发者友好 | 对 React 开发者友好 |
四、注意事项
通用注意点
环境适配:
-
避免在服务器端代码中使用浏览器 API(如 window、document)。
-
在 Vue 的 asyncData 或 React 的 getServerSideProps 中处理数据获取。
代码同构:
-
确保组件在服务端和客户端渲染结果一致(避免随机值、时间差等)。
性能优化:
-
使用缓存(如 Redis)减少重复渲染。
-
结合 CDN 加速静态资源分发。
Vue 专属注意点
-
使用 nuxtServerInit 在 Vuex Store 中初始化服务端数据。
-
通过 <client-only> 标签包裹仅需在客户端运行的组件。
React 专属注意点
-
在 useEffect 中处理客户端逻辑(如事件绑定)。
-
使用 dynamic 导入实现组件懒加载:
import dynamic from 'next/dynamic';
const ClientSideComponent = dynamic(() => import('../components/ClientComponent'), { ssr: false });
五、示例总结
-
Vue (Nuxt.js):适合快速构建内容驱动型应用(如博客、电商),依赖 Nuxt 的约定式配置。
-
React (Next.js):适合复杂交互与动态数据结合的场景(如用户仪表盘),灵活性更高。
通过框架(Nuxt/Next)的封装,开发者无需手动配置 Webpack 和服务端渲染逻辑,只需专注业务代码即可实现高性能 SSR。
评论前必须登录!
注册