【SSR】SSR 到底做了什么(用最简单的方式)

SSR 到底做了什么(用最简单的方式)

文章目录

  • [SSR 到底做了什么(用最简单的方式)](#SSR 到底做了什么(用最简单的方式))
  • [支持 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
         ↓
[后台进行] 服务器请求数据 → 服务器渲染

关键原因:

  1. 并行变串行

    • CSR:用户必须等JS下载完,才能开始请求数据(串行)
    • SSR:服务器一边请求数据,一边已经给用户发HTML了(并行)
  2. 网络环境不同

    复制代码
    用户网络:家里WiFi → 你的服务器(可能慢)
    服务器网络:机房内网 → 你的服务器(光速)
  3. 计算能力不同

    • 用户手机:渲染页面可能卡顿
    • 服务器:高性能CPU,渲染飞快

实际例子

场景:打开商品列表页

CSR 体验(用户视角):

  1. 看到空白页面(3秒)
  2. 看到加载动画(2秒)
  3. 突然出现商品列表

SSR 体验(用户视角):

  1. 立即看到商品列表(可能先看到骨架屏)
  2. 稍后图片加载、按钮可点击

技术细节(简单版)

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 像点外卖:

  1. 你下单(请求页面)
  2. 餐厅做菜(服务器给空HTML)
  3. 外卖员送餐(下载JS文件)
  4. 你收到食材(收到JS)
  5. 你自己做饭(JS请求数据并渲染)
    结果:要等很久才能吃

SSR 像堂食:

  1. 你进餐厅(请求页面)
  2. 厨房做菜(服务器请求数据并渲染)
  3. 服务员直接上菜(发送完整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 不是魔法,它有代价:

  1. 服务器压力大:每个用户访问,服务器都要渲染一次
  2. 开发复杂:要考虑代码在服务器和浏览器都能运行
  3. 交互延迟:虽然内容先出来,但要等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年)

  1. 新手/快速上手:Next.js(React)或 Nuxt.js(Vue)
  2. 企业项目:Next.js(大公司多用)
  3. 个人博客:Astro 或 Gatsby
  4. 学习原理:从 Vue/React 手动 SSR 开始
  5. 性能至上: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

关键点

  1. Next.js 和 Nuxt.js 是最安全的选择(生态成熟)
  2. SSR 不是银弹,根据需求选择
  3. 混合渲染是未来趋势(SSR + CSR)
  4. 从 CSR 开始,需要时再上 SSR

选择框架时,考虑团队熟悉度、社区支持和项目需求,不要盲目追求新技术!

相关推荐
容沁风3 小时前
react路由Cannot GET错误
前端·react.js·前端框架·sharp7
xjf77116 小时前
TypDom框架分析
javascript·typescript·前端框架·typedom
飞雪飘摇2 天前
Elpis 动态组件扩展设计:配置驱动的边界与突破
前端框架·全栈
PD我是你的真爱粉3 天前
Vue3核心语法回顾与Composition深入
前端框架·vue
colicode3 天前
Objective-C语音验证码接口API示例代码:老版iOS应用接入语音验证教程
前端·c++·ios·前端框架·objective-c
国产化创客3 天前
ESP32平台嵌入式Web前端框架选型分析
前端·物联网·前端框架·智能家居
前端达人4 天前
都2026年了,还在用Options API?Vue组合式API才是你该掌握的“正确姿势“
前端·javascript·vue.js·前端框架·ecmascript
colicode4 天前
C#语音验证码API示例代码:快速实现.NET环境下的语音验证调用逻辑
前端·前端框架·语音识别
colicode4 天前
C++语音验证码接口API示例代码详解:高性能C++语音校验接入Demo
前端·c++·前端框架·语音识别