Skip to content

预渲染

预渲染(Prerendering)是在构建时生成静态 HTML 页面,而不是在用户请求时动态渲染。预渲染的页面可以部署到任何静态托管,无需 Node.js 服务器。

预渲染 vs SSR vs SSG

特性预渲染(Prerender)SSRSSG
渲染时机构建时请求时构建时(全量)
服务器需求无(纯静态)Node.js 服务器无(纯静态)
内容更新需要重新构建实时需要重新构建
性能最快(静态文件)中等最快(静态文件)
适用场景静态页面动态内容博客、文档

预渲染 vs SSG

  • 预渲染:选择性渲染部分页面(Nuxt 的默认方式)
  • SSG(静态站点生成):渲染所有页面
  • Nuxt 4 中,nuxt generate + prerender 配置 = SSG

Nuxt 4 的混合渲染

你可以在同一个项目中,对不同的路由使用不同的渲染模式——部分预渲染、部分 SSR、部分 CSR。

routeRules 配置

通过 routeRules 配置哪些页面需要预渲染:

ts
export default defineNuxtConfig({
  routeRules: {
    // 预渲染指定页面
    '/': { prerender: true },
    '/about': { prerender: true },
    '/pricing': { prerender: true },

    // 预渲染特定动态路由
    '/blog/post-1': { prerender: true },
    '/blog/post-2': { prerender: true },
  },
})

prerender: true 的效果

构建时访问该页面,生成静态 HTML 文件。后续访问直接返回静态文件,不再执行服务端渲染。

Nitro 预渲染配置

更详细的预渲染配置在 nitro.prerender 中:

ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      // 预渲染路由列表
      routes: ['/', '/about', '/pricing'],

      // 自动爬取链接(发现页面中的内部链接,自动预渲染)
      crawlLinks: true,

      // 忽略路由(不预渲染)
      ignore: [
        '/admin/**',    // 管理后台不需要预渲染
        '/api/**',      // API 不需要预渲染
        '/dashboard',   // 需要登录的页面
      ],

      // 并发数(构建时同时渲染的页面数)
      concurrency: 10,
    },
  },
})

crawlLinks: true 的原理

  1. 渲染 routes 中指定的页面
  2. 解析页面中的所有 <a href="..."> 链接
  3. 如果链接指向同站页面,自动加入预渲染队列
  4. 递归爬取,直到没有新页面

INFO

crawlLinks 可能导致构建时间过长:如果网站有大量页面 建议配合 ignore 排除不需要预渲染的页面

动态路由预渲染

动态路由(如 /blog/[id]默认不会被预渲染——因为构建时不知道有哪些具体的 ID。需要手动指定:

方式 1:列出所有路由

ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: [
        '/',
        '/blog',
        '/blog/1',
        '/blog/2',
        '/blog/3',
      ],
    },
  },
})

方式 2:从 API 获取路由列表(推荐)

ts
// nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    async 'nitro:config'(nitroConfig) {
      // 从 API 获取所有博客文章 ID
      const posts = await $fetch('https://api.example.com/posts')
      const routes = posts.map(post => `/blog/${post.id}`)

      // 添加到预渲染列表
      nitroConfig.prerender?.routes?.push(...routes)
    },
  },
})

nitro:config 钩子

在 Nitro 配置生成后、构建开始前执行。可以动态修改预渲染列表。

方式 3:使用 prerenderRoutes

在页面中声明预渲染的路由:

vue
<script setup>
// 预渲染相关页面
prerenderRoutes(['/blog/1', '/blog/2'])
</script>

prerenderRoutes 的原理

在当前页面预渲染时,将指定路由加入预渲染队列。适合在列表页中自动预渲染详情页。

预渲染 + 缓存策略(SWR/ISR)

预渲染配合缓存策略,实现静态内容 + 定时更新的混合模式:

SWR(Stale-While-Revalidate)

ts
export default defineNuxtConfig({
  routeRules: {
    // 首页:预渲染 + 缓存 1 小时
    '/': { prerender: true, swr: 3600 },

    // 博客列表:ISR(60 秒后重新验证)
    '/blog/**': { isr: 60 },

    // 文档页面:预渲染 + 缓存 24 小时
    '/docs/**': { prerender: true, swr: 86400 },

    // API:不预渲染
    '/api/**': { cors: true },
  },
})

SWR vs ISR

策略行为适用场景
swr: 3600返回缓存(最多 1 小时),后台刷新内容更新不频繁
isr: 60返回缓存,60 秒后标记为过期,下次请求时刷新内容定期更新
isr: true返回缓存,直到手动清除手动控制更新

ISR(Incremental Static Regeneration)

ts
export default defineNuxtConfig({
  routeRules: {
    // 博客文章:ISR 5 分钟
    '/blog/**': { isr: 300 },
  },
})

ISR 的工作流程:

text
1. 首次请求 → 渲染页面 → 缓存 → 返回
2. 5 分钟内请求 → 直接返回缓存(快!)
3. 5 分钟后首次请求 → 返回旧缓存 + 后台重新渲染
4. 下次请求 → 返回新缓存

ISR 需要 Node.js 服务器或支持缓存的平台

纯静态部署(如 GitHub Pages)不支持 ISR。

ISR 支持的平台

Node.js、Vercel、Cloudflare、Netlify 等。

静态站点生成(SSG)

如果要生成完全的静态站点(所有页面预渲染):

ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,   // 自动爬取所有链接
    },
  },
})
bash
npx nuxt generate

输出到 .output/public/,可以直接部署到任何静态托管。

SSG 的优缺点

优点缺点
最快的加载速度内容更新需要重新构建
无需服务器动态路由需要手动指定
可部署到 CDN构建时间长(页面多时)
安全性高(无服务端)无法处理用户特定的内容

混合渲染模式

Nuxt 4 支持在同一项目中混合使用不同的渲染模式:

ts
export default defineNuxtConfig({
  routeRules: {
    // 静态页面:预渲染
    '/': { prerender: true },
    '/about': { prerender: true },
    '/pricing': { prerender: true },

    // 博客:ISR
    '/blog/**': { isr: 300 },

    // 管理后台:仅客户端渲染
    '/admin/**': { ssr: false },

    // API:标准 SSR
    '/api/**': { cors: true },

    // 重定向
    '/old-path': { redirect: '/new-path' },
  },
})

混合渲染的优势

  • 首页和营销页面预渲染 → 最快加载
  • 博客等动态内容用 ISR → 自动更新
  • 管理后台用 CSR → 无需 SSR
  • 同一个项目,不同路由不同策略

部署预渲染站点

bash
# 生成静态文件
npx nuxt generate

# 预览
npx nuxt preview

# 部署 .output/public/ 到静态托管
# - GitHub Pages
# - Netlify
# - Vercel
# - Cloudflare Pages
# - 阿里云 OSS + CDN
# - EdgeOne Pages

选择部署平台

  • 纯静态站点:GitHub Pages、Netlify、Cloudflare Pages
  • 需要 ISR:Vercel、Node.js 服务器
  • 中国用户:阿里云 OSS + CDN、EdgeOne Pages

知识脉络

text
API 路由 → 服务路由 → 服务中间件 → 服务插件 → 工具函数 → 事件处理 → 你在这里:预渲染

                                                                              ├─→ 相关:核心概念 → 渲染模式

                                                                              └─→ 相关:部署上线 → 构建命令

基于 Nuxt 4 官方文档整理编写