SSR 到底做了什么(用最简单的方式)
文章目录
- [SSR 到底做了什么(用最简单的方式)](#SSR 到底做了什么(用最简单的方式))
-
- [SSR 的关键步骤](#SSR 的关键步骤)
-
- [普通 CSR(客户端渲染)流程:](#普通 CSR(客户端渲染)流程:)
- SSR(服务器端渲染)流程:
- 后端接口是同一个吗?
- [为什么 SSR 能提升速度?](#为什么 SSR 能提升速度?)
- 实际例子
- 技术细节(简单版)
-
- [SSR 服务器做了什么:](#SSR 服务器做了什么:)
- [对比 CSR:](#对比 CSR:)
- 最直观的比喻
-
- [点外卖 vs 堂食](#点外卖 vs 堂食)
- 实际数据对比
- 重要提醒
- 一句话总结
- [支持 SSR 的主流框架大全](#支持 SSR 的主流框架大全)
-
- [📊 快速概览表](#📊 快速概览表)
- 详细分类介绍
-
- [🏆 React 生态](#🏆 React 生态)
-
- [1. **Next.js**(最流行)](#1. Next.js(最流行))
- [2. **Remix**](#2. Remix)
- [3. **Gatsby**(静态生成为主)](#3. Gatsby(静态生成为主))
- [💚 Vue 生态](#💚 Vue 生态)
-
- [1. **Nuxt.js**(Vue 官方推荐)](#1. Nuxt.js(Vue 官方推荐))
- [2. **Quasar**](#2. Quasar)
- [⚡ 其他框架](#⚡ 其他框架)
-
- [1. **SvelteKit**(新兴热门)](#1. SvelteKit(新兴热门))
- [2. **Angular Universal**](#2. Angular Universal)
- [3. **Astro**(内容优先)](#3. Astro(内容优先))
- [🆚 框架对比](#🆚 框架对比)
-
- 按使用场景选择
-
- [1. **企业官网/电商(需要 SEO)**](#1. 企业官网/电商(需要 SEO))
- [2. **后台管理系统(部分页面需要 SEO)**](#2. 后台管理系统(部分页面需要 SEO))
- [3. **博客/文档站**](#3. 博客/文档站)
- [4. **需要极致性能**](#4. 需要极致性能)
- [🚀 快速上手示例](#🚀 快速上手示例)
-
- [Next.js 入门(5分钟)](#Next.js 入门(5分钟))
- [Nuxt.js 入门(5分钟)](#Nuxt.js 入门(5分钟))
- [🔧 从零搭建简易 SSR(了解原理)](#🔧 从零搭建简易 SSR(了解原理))
-
- [Vue 3 + Vite SSR 最小示例](#Vue 3 + Vite SSR 最小示例)
- [📈 如何选择?](#📈 如何选择?)
- [💡 实际项目建议](#💡 实际项目建议)
- [🎯 总结](#🎯 总结)
SSR 的关键步骤
普通 CSR(客户端渲染)流程:
1. 浏览器请求 → 2. 收到空HTML → 3. 下载JS → 4. 执行JS → 5. JS请求数据 → 6. 等待数据 → 7. 渲染页面
用户需要等 3-7 步才能看到内容
SSR(服务器端渲染)流程:
1. 浏览器请求 → 2. 服务器请求数据 → 3. 服务器渲染HTML → 4. 发送完整HTML给浏览器 → 5. 立即显示
用户在第4步就看到内容了
后端接口是同一个吗?
是的,完全同一个接口,只是请求的人变了:
CSR(客户端请求):
用户浏览器 → 请求 /api/products → 后端服务器
- 用户电脑请求数据
- 走的是用户的网络,可能很慢
SSR(服务器请求):
用户浏览器 → 请求页面 → 你的服务器 → 请求 /api/products → 后端服务器
- 你的服务器请求数据
- 走的是机房内网,速度快得多
为什么 SSR 能提升速度?
对比图:
CSR 时间线:
[用户等3秒] 请求页面 → 下载JS → JS请求数据 → 等待数据 → 渲染
SSR 时间线:
[用户立即看到] 请求页面 → 收到完整HTML
↓
[后台进行] 服务器请求数据 → 服务器渲染
关键原因:
-
并行变串行:
- CSR:用户必须等JS下载完,才能开始请求数据(串行)
- SSR:服务器一边请求数据,一边已经给用户发HTML了(并行)
-
网络环境不同:
用户网络:家里WiFi → 你的服务器(可能慢) 服务器网络:机房内网 → 你的服务器(光速) -
计算能力不同:
- 用户手机:渲染页面可能卡顿
- 服务器:高性能CPU,渲染飞快
实际例子
场景:打开商品列表页
CSR 体验(用户视角):
- 看到空白页面(3秒)
- 看到加载动画(2秒)
- 突然出现商品列表
SSR 体验(用户视角):
- 立即看到商品列表(可能先看到骨架屏)
- 稍后图片加载、按钮可点击
技术细节(简单版)
SSR 服务器做了什么:
javascript
// 当用户访问 /products 时
async function handleRequest(request) {
// 1. 服务器先请求数据(内网,很快)
const products = await fetch('http://api-server/products');
// 2. 服务器生成完整HTML(用Vue/React渲染)
const html = `
<html>
<body>
<div id="app">
<h1>商品列表</h1>
${products.map(p => `<div>${p.name}</div>`).join('')}
</div>
</body>
</html>
`;
// 3. 把完整HTML发给用户
return html;
}
对比 CSR:
javascript
// CSR 返回给用户的HTML
const csrHtml = `
<html>
<body>
<div id="app"></div> <!-- 空的! -->
<script src="app.js"></script>
</body>
</html>
`;
// app.js 在用户浏览器中执行:
// 1. 下载 app.js(可能很大)
// 2. 请求数据 /api/products(用户网络)
// 3. 生成HTML并插入到页面
最直观的比喻
点外卖 vs 堂食
CSR 像点外卖:
- 你下单(请求页面)
- 餐厅做菜(服务器给空HTML)
- 外卖员送餐(下载JS文件)
- 你收到食材(收到JS)
- 你自己做饭(JS请求数据并渲染)
结果:要等很久才能吃
SSR 像堂食:
- 你进餐厅(请求页面)
- 厨房做菜(服务器请求数据并渲染)
- 服务员直接上菜(发送完整HTML)
结果:立刻就能吃
实际数据对比
假设每个环节的时间:
| 环节 | 用户网络 | 服务器内网 |
|---|---|---|
| 请求HTML | 100ms | 100ms |
| 下载JS | 1500ms | - |
| 请求API数据 | 500ms | 50ms |
| 渲染页面 | 200ms | 50ms |
CSR 总时间:
100ms + 1500ms + 500ms + 200ms = 2300ms(用户2.3秒后才看到内容)
SSR 总时间:
100ms(请求页面)→ 立即收到HTML
后台同时进行:50ms(请求数据)+ 50ms(渲染)
用户感觉:100ms后就看到内容了
重要提醒
SSR 不是魔法,它有代价:
- 服务器压力大:每个用户访问,服务器都要渲染一次
- 开发复杂:要考虑代码在服务器和浏览器都能运行
- 交互延迟:虽然内容先出来,但要等JS下载完才能点击
一句话总结
SSR 快是因为:
服务器用它的高速网络 和强大CPU ,提前把页面渲染好,用户直接拿成品,不用自己慢慢组装。
支持 SSR 的主流框架大全
📊 快速概览表
| 框架 | 技术栈 | SSR 支持 | 特点 | 适合场景 |
|---|---|---|---|---|
| Next.js | React | ⭐⭐⭐⭐⭐ | 最成熟、生态最全 | 企业官网、电商、博客 |
| Nuxt.js | Vue | ⭐⭐⭐⭐⭐ | Vue 生态最佳选择 | 企业官网、内容站 |
| Gatsby | React | ⭐⭐⭐⭐ | 专注于静态站点 | 文档、博客、营销页 |
| Angular Universal | Angular | ⭐⭐⭐⭐ | Angular 官方方案 | 企业级复杂应用 |
| SvelteKit | Svelte | ⭐⭐⭐⭐ | 轻量高性能 | 高性能要求应用 |
| Remix | React | ⭐⭐⭐⭐ | 数据加载优化 | 数据密集型应用 |
| Astro | 多框架 | ⭐⭐⭐ | 岛屿架构 | 内容为主网站 |
| Qwik | JSX | ⭐⭐⭐ | 零延迟可交互 | 极致性能要求 |
详细分类介绍
🏆 React 生态
1. Next.js(最流行)
bash
# 创建 Next.js 项目(默认支持 SSR)
npx create-next-app@latest
特点:
- 开箱即用的 SSR/SSG/ISR
- 文件系统路由
- API 路由(无需额外后端)
- 图片优化、字体优化
- 中间件支持
示例:
javascript
// pages/product/[id].js
export default function ProductPage({ product }) {
return <h1>{product.name}</h1>;
}
// SSR:每次请求都执行
export async function getServerSideProps(context) {
const res = await fetch(`/api/products/${context.params.id}`);
const product = await res.json();
return { props: { product } };
}
2. Remix
bash
# 创建 Remix 项目
npx create-remix@latest
特点:
- 嵌套路由,并行数据加载
- 表单处理优化
- 错误边界处理
- 渐进增强
示例:
javascript
// app/routes/products.$id.js
export async function loader({ params }) {
const product = await getProduct(params.id);
return json(product);
}
export default function Product() {
const product = useLoaderData();
return <h1>{product.name}</h1>;
}
3. Gatsby(静态生成为主)
bash
# 创建 Gatsby 项目
npm init gatsby
特点:
- 基于 GraphQL 数据层
- 插件生态系统丰富
- 性能优化出色
- 适合内容型网站
💚 Vue 生态
1. Nuxt.js(Vue 官方推荐)
bash
# 创建 Nuxt 3 项目
npx nuxi@latest init my-app
特点:
- 自动导入组件
- 文件系统路由
- 强大的模块系统
- 支持 SSG/SSR/SPA
示例:
vue
<!-- app.vue -->
<template>
<div>
<h1>{{ product.name }}</h1>
</div>
</template>
<script setup>
// 服务端获取数据
const { data: product } = await useFetch('/api/product/123');
</script>
2. Quasar
bash
# 创建 Quasar 项目
npm init quasar
特点:
- 一套代码,多端部署
- 内置大量 UI 组件
- 支持 PWA、移动端、桌面端
⚡ 其他框架
1. SvelteKit(新兴热门)
bash
# 创建 SvelteKit 项目
npm create svelte@latest
特点:
- 编译时框架,运行时极轻
- 开发者体验优秀
- 文件系统路由
- 热更新快
示例:
svelte
<!-- src/routes/product/[id]/+page.server.js -->
export async function load({ params }) {
const product = await getProduct(params.id);
return { product };
}
<!-- src/routes/product/[id]/+page.svelte -->
<script>
export let data;
const { product } = data;
</script>
<h1>{product.name}</h1>
2. Angular Universal
bash
# 添加 SSR 到现有 Angular 项目
ng add @nguniversal/express-engine
特点:
- Angular 官方解决方案
- 适合大型企业应用
- 完整的 TypeScript 支持
3. Astro(内容优先)
bash
# 创建 Astro 项目
npm create astro@latest
特点:
- 岛屿架构(Islands Architecture)
- 支持 React、Vue、Svelte 组件
- 默认零 JS 发送
- 非常适合内容网站
示例:
astro
---
// src/pages/product.astro
const product = await fetchProduct();
---
<html>
<body>
<!-- 静态内容(SSR) -->
<h1>{product.name}</h1>
<!-- 交互式组件(CSR) -->
<ProductGallery client:load />
</body>
</html>
🆚 框架对比
按使用场景选择
1. 企业官网/电商(需要 SEO)
✅ Next.js(React 团队) - 生态最成熟
✅ Nuxt.js(Vue 团队) - Vue 最佳选择
✅ Gatsby - 内容营销站
2. 后台管理系统(部分页面需要 SEO)
✅ Next.js - 混合渲染能力强
✅ Nuxt.js - 同样支持混合模式
⚠️ Gatsby - 不太适合
3. 博客/文档站
✅ Gatsby - 静态生成快
✅ Astro - 岛屿架构性能好
✅ Next.js - ISR 适合动态内容
4. 需要极致性能
✅ SvelteKit - 运行时最小
✅ Qwik - 可交互时间最快
✅ Astro - 默认零 JS
🚀 快速上手示例
Next.js 入门(5分钟)
bash
# 1. 创建项目
npx create-next-app@latest my-app
cd my-app
# 2. 创建 SSR 页面
mkdir -p pages/products && cd pages/products
cat > [id].js << 'EOF'
export default function Product({ data }) {
return <h1>{data.name}</h1>;
}
export async function getServerSideProps(context) {
const res = await fetch(`https://api.example.com/products/${context.params.id}`);
const data = await res.json();
return { props: { data } };
}
EOF
# 3. 运行
npm run dev
# 访问 http://localhost:3000/products/1
Nuxt.js 入门(5分钟)
bash
# 1. 创建项目
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
# 2. 创建 SSR 页面
mkdir -p pages/products && cd pages/products
cat > [id].vue << 'EOF'
<template>
<div>
<h1>{{ product.name }}</h1>
<p>{{ product.description }}</p>
</div>
</template>
<script setup>
const route = useRoute();
const { data: product } = await useFetch(
`https://api.example.com/products/${route.params.id}`
);
</script>
EOF
# 3. 运行
npm run dev
🔧 从零搭建简易 SSR(了解原理)
如果你想知道 SSR 底层原理:
Vue 3 + Vite SSR 最小示例
javascript
// server.js
import express from 'express';
import { createSSRApp } from 'vue';
import { renderToString } from '@vue/server-renderer';
const app = express();
app.get('*', async (req, res) => {
// 1. 创建 Vue 应用
const vueApp = createSSRApp({
data: () => ({ message: 'Hello SSR!' }),
template: `<div>{{ message }}</div>`
});
// 2. 渲染为 HTML
const html = await renderToString(vueApp);
// 3. 发送完整 HTML
res.send(`
<!DOCTYPE html>
<html>
<head><title>Vue SSR</title></head>
<body>
<div id="app">${html}</div>
<script>
// 水合脚本稍后加载
window.__INITIAL_STATE__ = {};
</script>
</body>
</html>
`);
});
app.listen(3000);
📈 如何选择?
选择框架的决策树
开始
↓
我需要 SSR 吗?
├─ 不需要 → 用 Vite + Vue/React (CSR)
└─ 需要 ↓
我的技术栈是?
├─ React → 选 Next.js
├─ Vue → 选 Nuxt.js
├─ Svelte → 选 SvelteKit
├─ 多框架混合 → 选 Astro
└─ 极致性能 → 选 Qwik
推荐选择(2024年)
- 新手/快速上手:Next.js(React)或 Nuxt.js(Vue)
- 企业项目:Next.js(大公司多用)
- 个人博客:Astro 或 Gatsby
- 学习原理:从 Vue/React 手动 SSR 开始
- 性能至上:SvelteKit
💡 实际项目建议
项目类型与框架推荐
| 项目规模 | 推荐框架 | 理由 |
|---|---|---|
| 初创公司 MVP | Next.js | 快,生态好,招人容易 |
| 电商平台 | Next.js/Nuxt.js | SEO 必须,性能关键 |
| 技术博客 | Astro | 性能极好,写文章舒服 |
| 后台管理系统 | Next.js | 可混合渲染,权限管理方便 |
| 个人作品集 | SvelteKit | 酷,性能好,适合展示 |
| 大型企业应用 | Angular Universal | TypeScript 友好,架构严谨 |
学习路线建议
阶段 1:学习 React/Vue 基础
阶段 2:体验 CSR 项目(Vite)
阶段 3:学习 Next.js/Nuxt.js
阶段 4:深入了解 SSR 原理
阶段 5:根据项目需求选型
🎯 总结
一句话推荐
- React 项目 → Next.js
- Vue 项目 → Nuxt.js
- 内容网站 → Astro
- 追求性能 → SvelteKit
- 学习原理 → 手动实现 SSR
关键点
- Next.js 和 Nuxt.js 是最安全的选择(生态成熟)
- SSR 不是银弹,根据需求选择
- 混合渲染是未来趋势(SSR + CSR)
- 从 CSR 开始,需要时再上 SSR
选择框架时,考虑团队熟悉度、社区支持和项目需求,不要盲目追求新技术!