Skip to content

渲染模式

在 Nuxt 中,支持多种渲染模式:

预渲染#

对应的英文为 prerendering,是一种在构建阶段提前生成静态 html 文件的技术,通过提前生成静态的 html,可以提升页面的加载性能以及 seo 优化。

这里需要注意,预渲染是一种技术,而 SSR、SSG、SPA 是一种渲染模式或者说渲染策略。

配置预渲染

  1. 配置文件中配置

    export default defineNuxtConfig({
    nitro: {
    prerender: {
    // 指定预渲染首页以及产品列表页
    routes: ['/', '/products'],
    },
    },
    })
  2. 页面组件中配置

    pages/products.vue
    <script setup>
    definePageMeta({
    prerender: true,
    })
    </script>

    之后就会进行一个转换,转换为一个应用配置:

    export default defineNuxtConfig({
    routeRules: {
    '/products': {
    prerender: true,
    },
    },
    })

在 Nuxt 中,默认开启 crawlLinks: true,类似于一个爬虫,它会自动分析页面中的链接,将相应的链接也一起进行预渲染。

但是以下场景无法自动爬取:

  1. 动态路由未被其他页面链接:/posts/[id].vue,但是预渲染的页面没有链接到具体的页面,也就是说不存在诸如 /posts/1、/posts/2 这种路由链接

  2. 动态参数依赖外部数据,此时就可以做 构建运行时的预渲染配置

    什么是构建运行时?Nuxt在构建应用的时候,会启动一个临时服务器,完整的运行整个应用的逻辑(相当于将整个应用跑了一遍),注意一定要和应用部署后的运行时区分开。

    // 因此可以在构建运行时请求外部数据,生成完整的路由列表
    export default defineNuxtConfig({
    nitro: {
    prerender: {
    routes: async () => {
    // 发送真实请求,拿到外部数据
    const posts = await fetch('xxxx').then((res) => res.json())
    // 这里返回的就是完整的路由列表,相当于['posts/1', 'posts/2', ...]
    return posts.map((post) => `/posts/${post.id}`)
    },
    },
    },
    })
  3. 非 html 路由:/xxx.xml、/xxx.txt 这些属于非页面路由,也无法被爬取

SSR#

这是 Nuxt 中默认的渲染模式,不需要任何的配置。

image-20250201153519784

思考🤔:SSR 中有用到预渲染技术么?

预渲染指的是在 构建阶段 提前生成 html 的技术。ssr 是根据用户的请求动态的生成首屏 html。ssr 可以看作是一种请求时的动态预渲染。

SSG#

英文全称为“static site generate”,翻译成中文是“静态站点生成”,顾名思义,就是将整个站点都生成静态的 html。

SSG 就是上面所介绍的预渲染技术的一种应用,与 SSR 之间的区别在于:

SSG 一般适用于内容相对固定、无需频繁实时更新的应用场景,一般应用都是以静态内容为主

在 Nuxt3 中,需要全站以 SSG 模式来渲染的话,可以使用命令:

Terminal window
npx nuxi generate

生成的静态站点内容位于 .output/public 目录下面。

SPA#

Nuxt3 是一个全栈的上层框架,提供多种渲染模式的,因此自然也是支持 SPA 渲染模式的。

image-20250201153642785

在 Nuxt3 中要启用 SPA 渲染模式:

nuxt.config.ts
export default defineNuxtConfig({
ssr: false, // 关闭服务端渲染(SSR),启用 SPA 模式
})

路由模式有常见的两种:

路由模式特点示例
Hash模式使用 URL 的 # 符号后的部分作为路由路径http://example.com/#/about
History模式使用 HTML5 History API 作为路由路径http://example.com/about

虽然 SPA 支持这两种路由模式,但是 SSR 的话只能使用 History 模式。

思考🤔 为什么?

因为 SSR 的核心是根据用户的请求动态的生成 html,如果是 hash 模式,会导致服务器无法收到完整的路由信息。

混合渲染#

可以为一组 Nuxt 路由定义特定的规则,这包括改变一些路由的渲染模式或分配特定的缓存策略,从而决定服务器如何响应针对该 URL 的请求。

场景示例:

假设一个内容网站,其中大部分页面(如文章页面)都是静态内容,只需要在构建时生成一次,然后长期缓存;而网站的管理后台则需要用户登录、实时更新数据,必须每次都动态渲染。

通过混合渲染和路由规则,可以为文章页面设置缓存策略,让它们在构建时生成静态 HTML,同时为管理后台页面指定不缓存、每次请求都动态渲染。这样既保证了普通内容页面的加载速度和 SEO 优势,又满足了后台动态交互的需求。

具体配置示例:

export default defineNuxtConfig({
routeRules: {
// 将首页在构建时预渲染(prerender)
// 构建时生成静态 HTML,之后所有访问该路由的请求都直接返回这份预渲染好的内容,不再进行动态渲染。
// 这种方式适用于内容稳定且无需频繁更新的页面,有助于提高首屏加载速度和 SEO 表现。
'/': { prerender: true },
// Products 页面使用 SWR(Stale-While-Revalidate)策略
// 该页面在请求时会先返回缓存(即使数据已经“过时”),同时在后台重新获取最新数据,并在获取完成后更新缓存。
// 使用 true 表示采用默认的 SWR 策略,适用于数据可能变化但允许短暂显示缓存数据的场景。
'/products': { swr: true },
// 所有以 /products/ 开头的子路由页面也使用 SWR 策略,但缓存时间设置为 3600 秒(即 1 小时)。
// 对于产品详情等子页面,当用户访问时,若有缓存数据则直接返回,同时后台重新验证并更新数据。
// 数值 3600 表示缓存有效期为 1 小时,适用于数据更新频率较低,但又希望保持一定的实时性页面。
'/products/**': { swr: 3600 },
// Blog 主页使用 ISR(Incremental Static Regeneration)模式,缓存时间 3600 秒。
// 该页面在首次请求时会生成静态 HTML,并在后台以 ISR 模式定期重新生成(每 1 小时)。
// 这样既享有静态页面的加载速度,又能定期更新数据。适合新闻、博客列表等内容更新频率较低的页面。
'/blog': { isr: 3600 },
// 所有以 /blog/ 开头的子路由(比如单篇博客文章)使用 ISR 模式,但只在首次请求时生成静态页面,之后直到下次部署前都不重新生成。
// 设置为 true 表示对这些页面进行一次性生成静态 HTML,之后不再更新(或说直到下一次部署时才重新生成)。
// 这适用于博客文章内容固定不变的场景,可以极大提升缓存和分发效率。
'/blog/**': { isr: true },
// 所有以 /admin/ 开头的路由禁用 SSR,即仅在客户端渲染。
// 管理后台通常需要用户身份验证和实时交互,因此不适合预渲染。
// 设置 ssr: false 后,这部分页面会完全在客户端运行,避免了服务器端生成静态内容,从而确保动态交互的实时性和安全性。
'/admin/**': { ssr: false },
// 所有以 /api/ 开头的路由自动添加 CORS(跨域资源共享)头部。
// 对于 API 接口,通常需要允许跨域访问。
// 配置 cors: true 后,Nuxt 服务器会自动在响应中添加相应的 CORS 头,以满足跨域请求的要求。
'/api/**': { cors: true },
// 将旧的 URL 重定向到新的 URL。
// 当用户访问 /old-page 时,服务器会自动将请求重定向到 /new-page。
// 这对于旧链接的维护和 SEO 友好性非常有用,可以避免用户访问无效页面。
'/old-page': { redirect: '/new-page' },
},
})

关于更详尽的路由规则,可以参阅 官方文档


-EOF-