跳到主要内容

渲染方式

有的网站打开飞快,有的需要等待服务器响应?为什么有的页面内容更新需要重新部署,有的却能实时刷新?”答案就藏在“渲染模式"里。Nuxt/Next支持多种渲染模式,每种模式都有其独特的适用场景。

  • SSR(服务器端渲染)

  • CSR(客户端渲染)

  • SSG(静态站点生成)

  • ISR(增量静态再生)

模式HTML 生成时机打开速度SEO更新方式
CSR浏览器慢差实时
SSR每次请求中极好实时
SSG构建时最快极好重新部署
ISR构建 + 按需快极好自动刷新

SSR​

  • 服务端渲染,通过服务端生成页面(html)
  • 支持动态更新数据

优点

  • SEO 极好
  • 首屏体验好

缺点

  • 每次请求都打服务器
  • 高并发成本高
  • 页面打开速度受后端接口影响

CSR​

  • 客户端渲染,通过浏览器来生成页面

特点:

  • 首屏慢(白屏时间长)
  • 页面更新不需要重新部署
  • 对服务器压力小
  • SEO 很差(搜索引擎看到的是空壳)

SSG​

  • 打包时生成静态的页面
  • 体验效果:“点一下,瞬间出来”

特点:

  • 打开速度最快(CDN 直出)
  • SEO 极好
  • 内容变了要重新 build + deploy

场景:

  • 官网
  • 文档
  • 博客
  • 活动页
  • 落地页

ISR​

ISR 是增量静态再生。它会先缓存静态内容;当缓存过期后,下一次请求会触发重新生成,生成完成后再更新缓存,后续请求就会拿到新的静态内容

  • ISR:Incremental Static Regeneration(增量更新、增量静态生成)
  • (ISR)是一种结合了 SSR 和 SSG 优点的混合方法
  • 需要定期更新静态页面,可以理解为自动化更新的 SSG
  • ISR缓存的对象是 HTML 页面 + JSON 数据
    • 可以理解为:ISR 缓存的是 整个页面渲染结果
  • 行为:当缓存过期后,下一个请求会触发重新生成
  • ISR可以理解为 SSG + 动态更新的折中方案
  • ISR => “静态页面 + 过期时间 + 后台再生 + CDN 缓存”
  • ISR = Next / Nuxt 自己缓存 HTML,并在过期后自动后台刷新
  • ISR 缓存是在 Node 服务器进程(Nitro)内部,并且所有用户共享同一份缓存
  • 自动更新:过期后第一个请求 → 返回旧的缓存数据 → 后台会进行重新执行ssr相关逻辑重新渲染生成html → 写回缓存 → 后续请求用新的缓存
    • 在缓存的时间内,会先返回旧 HTML
    • 缓存过期后,后台重新生成新 HTML
  • Nuxt Nitro 的 isr 后台更新是无条件的,总是重新渲染并覆盖缓存,不会比较数据是否变化再决定是否写入

特点:

  • 不是每次都重新部署,而是“过期再生成”
  • 打开速度 接近 SSG
  • 内容可自动更新
  • 不用手动重新部署
  • 数据有短暂延迟

场景

  • 博客列表
  • 新闻
  • 商品列表
  • 榜单
  • 低频变更的内容页

实现方案​

  • ISR 不需要后端接口“主动配合”就能工作,只要 Nuxt / Next 本身就能完成 ISR
  • 后端是否配合缓存,决定 ISR 是“快”还是“只是不重建”

后端接口配合

  • HTTP Cache
  • CDN
  • ETag / Cache-Control

第一次访问

  • 这份 HTML 就是 ISR 缓存
txt
请求页面
↓
服务器请求接口
↓
生成 HTML
↓
缓存 HTML(时间戳 = now)

缓存时间内

  • 不会再请求接口
  • 不会重新生成页面
  • 打开速度 ≈ SSG
txt
请求页面
↓
缓存未过期
↓
直接返回缓存 HTML

ISR 缓存来源

不是浏览器缓存,不是CDN缓存

Next.js

  • Vercel:Edge / File Cache
  • 自部署:.next/cache
  • Cloudflare:KV / Edge Cache

Nuxt 3

  • Nitro Storage
  • Edge / Server Runtime Cache
  • 平台决定存哪(Vercel / CF / Node)

swr​

  • swr:Stale-While-Revalidate
  • 先给用户看“旧”的缓存,同时在后台静默更新
  • 行为:无论缓存是否过期,只要缓存里有东西,先扔给用户看。与此同时,服务器在后台跑去取新数据并更新缓存

swr和isr的 两者其实非常接近。通常 ISR 被用来描述那种“静态生成 + 定时刷新”的逻辑,而 SWR 被用来描述“先给旧数据,再异步刷新”的逻辑

相关问题​

  • 为什么有的页面更新要重新部署

    • 用的是 SSG
    • 构建时就把数据“写死”进 HTML
  • 为什么有的能实时刷新?

    • CSR:浏览器直接调接口
    • SSR:服务器实时渲染
    • ISR:后台自动再生数据更新
  • 判断页面是否缓存生效

    • next:观察 x-nextjs-cache 的状态变化

判断页面是否缓存生效​

  • next:观察 x-nextjs-cache 的状态变化
text
x-nextjs-cache: HIT
x-nextjs-cache: STALE
x-nextjs-cache: MISS
值含义
HIT缓存命中
STALEISR 过期,正在后台再生
MISS刚生成(SSR / 首次 ISR)

HIT 表示撞击,即命中,(直接使用缓存)

STALE 表示陈旧、过期, 即过期 (旧缓存返回 + 后台再生)

MISS 表示未命中, 即缓存未命中 (无缓存,重新生成)