Files
zhuangang/topics/frontend/ssr/01-rendering-modes.md
T

3.8 KiB
Raw Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
id title type domain stack tags level prerequisites est_hours related week order
frontend.ssr.rendering-modes 渲染模式:CSR / SSR / SSG / ISR、水合、流式渲染和 Nuxt 基础 lesson frontend
ssr
CSR
SSR
SSG
ISR
水合
Hydration
流式渲染
Nuxt
SEO
intermediate
frontend.vue.reactivity-composition
2.5
frontend.ssr.nextjs-app-router
frontend.fe-testing-perf.index
frontend.ssr.interview
7
1

渲染模式:CSR / SSR / SSG / ISR、水合、流式渲染和 Nuxt 基础

解释说明

模式 在哪里生成 HTML 优点 缺点 适合
CSR(客户端渲染) 浏览器执行 JS 后生成 服务器简单,交互流畅 首屏慢、SEO 差 后台系统、登录后的应用
SSR(服务端渲染) 每次请求时服务器生成 首屏快、SEO 好、数据实时 服务器压力、需要 Node 服务 内容和数据经常变化的公开页面
SSG(静态生成) 构建时生成 最快、可放 CDN 数据更新要重新构建 文档、官网、博客
ISR(增量静态再生成) 构建时生成 + 过期后后台重新生成 兼顾速度和更新 有短暂的旧数据 商品页、文章页

水合(Hydration):服务端返回 HTML 后,浏览器加载 JS,把事件监听和状态“接”到已有的 DOM 上,页面才可以交互。问题:

  • 水合不匹配:服务端和客户端渲染结果不一致(用了 Date.now()、Math.random()、window、本地时区),会报警告甚至重新渲染。
  • 首屏能看到但点不动(JS 还没加载完):通过减少客户端 JS、部分水合 / 服务端组件、懒加载缓解。

流式渲染:服务器先发送页面框架,慢的数据块准备好后再流式补上(React 的 Suspense、Next.js 的 loading.tsx),首字节更快。

Nuxt(Vue 的全栈框架,当前大版本 Nuxt 4,以官方文档为准:https://nuxt.com/docs):基于文件的路由、useFetch / useAsyncData 在服务端取数并把结果传给客户端避免重复请求、server/ 目录写接口(Nitro 引擎)、按路由配置渲染模式(routeRules:SSR、预渲染、ISR 类缓存)。

案例

电商的帮助中心:常见问题页需要 SEO 和最快的首屏,用 SSG / ISR;智能客服对话需要登录和实时交互,是客户端组件;订单页登录后才能看,用 CSR 或 SSR 都可以,但要注意不能把用户数据缓存到 CDN。

代码示例

避免水合不匹配:只在客户端执行的逻辑放到挂载之后。

<script setup lang="ts">
import { onMounted, ref } from "vue";

const now = ref<string | null>(null);          // 服务端渲染时为 null,两端一致
onMounted(() => {
  now.value = new Date().toLocaleString("zh-CN");   // 只在浏览器执行
});
</script>

<template>
  <span>{{ now ?? "加载中" }}</span>
</template>

Nuxt 中服务端取数(结果会序列化到页面中,客户端水合时不会再请求一次):

<script setup lang="ts">
const { data: faqs, error } = await useFetch("/api/faqs");
</script>

Next.js 的写法见下一课和 examples/next-ai-chat。

易错点

  • 在服务端渲染阶段访问 window、localStorage。
  • 服务端渲染时使用了全局单例状态(Pinia、模块级变量),导致不同用户的数据串在一起:每个请求要创建新的实例。
  • 把带用户信息的 SSR 页面缓存到 CDN。
  • SSR 页面里调用很慢的接口,拖慢整个首屏:并行取数、流式渲染、超时降级。
  • 以为用了 SSR 就一定更快:服务器离用户远、取数慢时,TTFB 反而变差。

面试常问

  • CSR、SSR、SSG、ISR 的区别和适用场景?
  • 什么是水合?水合不匹配的原因?
  • SSR 项目有哪些常见的坑?