首页 / Nuxt 4 入门教程 / 预渲染与混合渲染

Nuxt 4 入门教程

预渲染与混合渲染

本教程共 50 篇 · 第 43 篇 · 更新于 2026-08-08 · 约 8 分钟阅读

NuxtNuxt4预渲染prerenderrouteRules混合渲染SSG

本节目标:理解 Nuxt 的预渲染与混合渲染,会用 nuxt generaterouteRules 把合适的页面在构建时静态化,提升性能与 SEO。

43-1

默认 SSR 模式下,用户每次请求,服务器都现场渲染一次 HTML。对内容基本不变的页面(首页、关于页、博客文章),这其实是浪费。预渲染(prerendering)的思路是:在构建时就把这些页面渲染成静态 HTML 存好,用户请求时直接发文件,又快又省服务器资源,还顺带把 SEO 做到位。

可以把它理解成「提前把菜炒好放保温柜,客人来了直接端」,而不是「客人点单后再现做」。

Note

预渲染产出的不仅是 HTML,还会带上 _payload.json(构建时抓取的数据)。客户端导航到这些页面时,直接复用这份数据,不用再发一次请求。

43-2

最简单的全站静态化命令:

npx nuxt generate

Nuxt 会启动 Nitro 爬虫,从根路由 / 开始,渲染它能发现的所有页面,并记录页面里链接到的其他页面,一路爬下去。爬完后,产物在 .output/public/,可部署到任何静态托管。

你的应用
  └─ 根页面 /
       └─ 链接到 /about
            └─ 链接到 /blog/1
                 └─ ...(以此类推)
Warning

爬虫只能发现「页面里 <a href> 链接得到」的页面。纯动态路由(如 /blog/[id],靠接口数据生成的列表)如果页面上没有对应链接,爬虫就抓不到,自然不会被预渲染。这种页面要用下面讲的选择性预渲染兜底。

43-3

不想全站爬,就手动指定要预渲染的路由、忽略某些路由:

export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/user/1', '/user/2'],
      ignore: ['/dynamic'],
    },
  },
})

结合 crawlLinks: true,还能让爬虫预渲染它本来发现不了的资源(如 /sitemap.xml/robots.txt):

export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ['/sitemap.xml', '/robots.txt'],
    },
  },
})

43-4

更常用的方式是用 routeRules,给不同路由分组制定「渲染策略」。它既管预渲染,也管缓存:

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },              // 首页构建时渲染
    '/products/**': { swr: 3600 },         // 边缘缓存 1 小时(过期后后台刷新)
    '/blog': { isr: 3600 },                // 增量再生,1 小时重渲染
    '/admin/**': { ssr: false },           // 后台纯客户端渲染
    '/rss.xml': { prerender: true },
    '/this-page-skipped': { prerender: false },
    '/blog/**': { prerender: true },       // 只要从别处链接得到,整段博客都预渲染
  },
})

prerender/ssr/swr/isr 这些就是「混合渲染」的核心:同一个应用里,不同页面用不同策略。Nuxt 会自动注册对应中间件并用 Nitro 缓存层包裹。

Tip

页面级也可简写:在 .vue 文件里用 defineRouteRules({ prerender: true })(需开启 experimental.inlineRouteRules),Nuxt 会把它转成对应的 routeRules。小项目这么写在页面旁边更直观。

43-5

有些路由是 CMS 里的文章,构建时还不知道有哪些。可以用 prerenderRoutes 在页面运行时补充:

<script setup lang="ts">
prerenderRoutes(['/some/other/url'])
prerenderRoutes('/api/content/article/my-article')
</script>

或者在钩子里批量注册:

export default defineNuxtConfig({
  hooks: {
    async 'prerender:routes'(ctx) {
      const { pages } = await fetch('https://api.some-cms.com/pages').then(r => r.json())
      for (const page of pages) {
        ctx.routes.add(`/${page.name}`)
      }
    },
  },
})

还有 prerender:generate 钩子,能在每个路由预渲染时精细处理(比如跳过含 private 的路由)。

43-6

  • 营销页、文档、博客:内容稳定 → prerender
  • 商品列表:偶尔变 → swr/isr 边缘缓存。
  • 后台管理:强交互、弱 SEO → ssr: false 或仅客户端。
  • 一套代码,按路由分配策略,这就是 Nuxt 混合渲染的价值。
Warning

预渲染不是「越多越好」。会频繁变化的页面(实时 dashboard)不适合预渲染,否则用户看到的是过期的静态内容。先想清楚页面的更新频率,再选策略。

43-7

Nuxt 3 与 Nuxt 4 的预渲染机制(Nitro 爬虫、routeRulesprerenderRoutes)一致。app/ 约定只影响这些配置所在文件的位置,不影响语义。

43-8

npx nuxt generate 是「整站静态化」:它会启动爬虫,把所有能爬到的页面都渲染成 HTML,产物纯静态,能丢到任何静态托管(甚至不需要 Node 服务器)。prerender 路由规则则更灵活:你只在 routeRules 里挑几个页面预渲染,其余页面仍然走 SSR 或客户端渲染。

简单说:generate 是「全部做成静态文件」,prerender: true 是「这一个路由做成静态、其余照旧」。小博客用 generate 最省心;大站只想把首页、关于页静态化,就用 routeRules

43-9

routeRules 不只是开关预渲染,它还能直接管响应头和重定向:

export default defineNuxtConfig({
  routeRules: {
    '/old-blog': { redirect: { to: '/blog', statusCode: 301 } },
    '/api/**': { cors: true },
    '/static/**': { headers: { 'cache-control': 'max-age=31536000' } },
  },
})

redirect 做老链接迁移,cors 给接口开跨域,headers 给静态资源加长缓存。这些都是在配置里一行搞定,不用写额外服务端代码。

Warning

redirect 是 301 还是 302 要想清:永久迁移用 301(搜索引擎会更新收录),临时跳转用 302,用错会影响 SEO 权重。
预渲染不是零成本:构建时会真的去请求这些路由、把它们渲染成 HTML,页面越多、构建越慢。所以 prerender: true 适合「数量有限、更新不频繁」的页面,别把成千上万个商品详情页全丢进预渲染,那会让构建时间爆炸。验证预渲染是否生效很简单:构建后去 .output/public/ 看对应目录是不是生成了 .html 文件;有,说明预渲染成功;没有,多半是路由没被爬虫发现,回到前面「选择性预渲染」用 routes 显式列出即可。

Tip

上线前用 npx nuxt build 后翻一下 .output/public,确认你期望预渲染的页面都在。漏掉的页面会走 SSR,体验不至于坏,但 SEO 和首屏速度就少了一份保障。

43-10

nuxt generate 全站爬取预渲染,routeRules 按路由分配 prerender/swr/isr/ssr 实现混合渲染,动态路由用 prerenderRoutes 或钩子补注册。下一章我们看更通用的性能优化与缓存手段。

43-7 ISR 的实际应用场景

增量静态再生(ISR)是 Nuxt 支持的一种强大渲染模式。它结合了 SSG 的性能优势和 SSR 的实时性:页面首次被预渲染成静态文件,之后每隔一段时间自动重新生成。用户访问时始终拿到最新的静态页面,既快又新。

典型的应用场景包括:电商商品详情页(内容变化不频繁但需要定期更新价格和库存)、新闻文章(发布后偶尔需要修正)、文档站点(内容随版本迭代更新)。这些场景下,ISR 比纯 SSR 性能更好,比纯 SSG 内容更及时。

在 Nuxt 里配置 ISR 很简单,通过 routeRules 里的 swr 选项指定再生间隔即可。需要注意的是,再生过程是异步的,用户可能在短时间内看到旧版本的内容。对于不能接受任何延迟的场景,还是应该用 SSR。

43-8 预渲染与 CDN 的配合

预渲染生成的纯静态文件非常适合部署到 CDN(内容分发网络)。CDN 把文件缓存到全球各地的边缘节点,用户访问时从最近的节点获取,延迟极低。这种架构的承载能力非常强,即使突然遭遇流量高峰,CDN 也能轻松应对。

部署到 CDN 时,需要注意缓存刷新策略。当你更新了预渲染的页面后,CDN 上的旧缓存不会自动更新。大多数 CDN 提供了手动刷新或 API 刷新的方式。一些部署平台(如 Vercel、Netlify)在每次部署时会自动处理缓存刷新。

对于 ISR 模式的页面,CDN 需要支持边缘再生(Edge Regeneration)。不是所有 CDN 都支持这个特性,选择部署平台时要确认。Vercel 和 Cloudflare Pages 是目前支持较好的选择。