【Nuxt3系列十八】关键概念-渲染模式

711 阅读6分钟

Nuxt支持不同的渲染模式

  • 通用渲染
  • 客户端渲染
  • 混合渲染
  • CDN边缘服务器上渲染

通用渲染

通用渲染模式是服务器端+客户端一起使用的。服务器会首先向浏览器返回一个完整的HTML,这个HTML可能是构建的时候预渲染,也有可能是执行的时候再渲染出来的。这就是服务端渲染的步骤

然后为了不失去客户端渲染的优势,例如动态界面和页面过度,客户端再下载这个HTML之后,还会在后台加载原本在Server上运行的js代码。浏览器会再次解释调用它

这回使得这个静态页面,重新拥有了动态能力。这个过程叫做Hydration,水合作用

服务端渲染的好处

  • 性能:用户一下子就能获得完整的内容,响应更加快了
  • SEO: 搜索引擎一般只能爬取HTML,不会执行js。所以你的内容更加容易呈现给搜索引擎

服务端渲染的缺点

  • 开发麻烦,需要考虑不同环境下的api
  • 成本,服务器的成本增加了

客户端渲染

就像是传统的Vue项目一样。打包出来的html会执行main.js。这包含完整的Vue.js代码,然后开始解析用户的操作

好处:

  • 开发速度,更快了,而且只有一套浏览器的api
  • 便宜,运行成本转嫁给用户了
  • 离线,它允许用户下载完完整的代码后,离线运行一时间

缺点

  • 性能,用户要等待下载、解析和运行js文件
  • SEO不好,同上

Nuxt也提供这种方式

export default defineNuxtConfig({
  ssr: false
})

部署一个静态的客户端渲染的应用程序

如果你使用 nuxi generatenuxi build --prerender 命令将应用部署到静态托管服务上,那么默认情况下,Nuxt 会将每个页面渲染为单独的静态 HTML 文件。

如果你只使用客户端渲染,这可能是没有必要的。你只需一个index.html 文件,再加上 200.html404.html 的回退页面,你可以告诉你的静态网页托管服务对所有请求提供这些文件。 为了实现这一点,我们可以改变路由的预渲染方式。只需在你的 nuxt.config.ts 文件中的 hooks 添加以下内容:

export default defineNuxtConfig({
  hooks: {
    'prerender:routes' ({ routes }) {
      routes.clear() // Do not generate any routes (except the defaults)
    }
  },
})

然后,Nuxt只生成三个文件

  • index.html
  • 200.html
  • 404.html

混合渲染

如果你想有的部分使用通用渲染,有部分使用客户端渲染。也是可以的

例如一个CMS管理系统。一些向外展示的页面应该是静态的,但是管理后台需要注册功能,更像一个动态应用。

Nuxt支持在路由规则中设置渲染模式,以支持混合渲染。

export default defineNuxtConfig({
  routeRules: {
    // 构建的时候就进行预渲染
    '/': { prerender: true },
    // 产品页面按需生成,在后台重新验证,缓存直到API响应更改
    '/products': { swr: true },
    // 产品页面按需生成,后台重新验证,缓存1小时(3600秒)
    '/products/**': { swr: 3600 },
    // 博客文章页面按需生成,在后台重新验证,在CDN上缓存1小时(3600秒)
    '/blog': { isr: 3600 },
    // 博客文章页面按需生成一次,直到下一次部署,缓存在CDN上
    '/blog/**': { isr: true },
    // 管理仪表板只在客户端渲染
    '/admin/**': { ssr: false },
    // 在API路由中添加cors头
    '/api/**': { cors: true },
    // 重定向遗留url
    '/old-page': { redirect: '/new-page' }
  }
})

路由规则

你可以使用的不同属性如下:

  • redirect: string — 定义服务器端重定向。
  • ssr: boolean — 对应用程序的部分区域禁用服务器端渲染,并将其设置为仅单页应用(SPA)模式,通过设置 ssr: false 实现。
  • cors: boolean — 自动添加跨源资源共享(CORS)头部,通过设置 cors: true 实现。可以通过覆盖 headers 属性来定制输出。
  • headers: 对象 — 向网站的特定部分添加特定的头部信息——例如,你的资源文件。
  • swr: 数字或布尔值 — 向服务器响应添加缓存头部,并在服务器或反向代理上为可配置的存活时间(TTL)缓存该响应。Nitro 的 Node 服务器预设能够缓存完整的响应。当 TTL 到期后,会发送已缓存的响应,同时在后台重新生成页面。如果使用 true,则会添加一个无过期时间的验证缓存(stale-while-revalidate)头部,但不指定最大有效期(MaxAge)。
  • isr: 数字或布尔值 — 其行为与 swr 相同,只是我们能够在支持此功能的平台(目前为 Netlify 或 Vercel)上将响应添加到内容分发网络(CDN)缓存中。如果使用 true,则内容会在 CDN 中保留到下一次部署。
  • prerender: 布尔值 — 在构建时预先渲染路由,并将它们作为静态资源包含在构建中。
  • experimentalNoScripts: 布尔值 — 对网站的部分区域禁用 Nuxt 脚本和 JavaScript 资源提示的渲染。
  • appMiddleware: 字符串、字符串数组或记录类型(键为字符串,值为布尔值)——允许你定义应该或不应该在 Vue 应用程序部分(即,非 Nitro 路由)的页面路径中运行的中间件。

边缘渲染

这是一个Nuxt引入的强大的功能,它使得Nuxt像静态网站一样支持CDN分发。

边缘侧渲染的工作原理是将渲染过程推送到网络的“边缘”位置,即 CDN 的边缘服务器。需要注意的是,ESR 更多是一种部署目标而非实际的渲染模式。

当请求某个页面时,请求不会直接到达原始服务器,而是被最近的边缘服务器截获。这个服务器会生成页面的 HTML 并将其发送回用户。这一过程减少了数据传输的实际距离,降低了延迟,并加快了页面加载速度

边缘侧渲染得以实现要归功于 Nitro,这是为 Nuxt 3 提供动力的服务器引擎。Nitro 支持跨平台,包括 Node.js、Deno、Cloudflare Workers 等。

目前可以利用边缘侧渲染的平台有:

  • 使用 Git 集成和 nuxt build 命令,在 Cloudflare Pages 上无需任何配置即可实现边缘侧渲染。
  • 使用 nuxt build 命令和环境变量 NITRO_PRESET=vercel-edge 在 Vercel 边缘函数上启用边缘侧渲染。
  • 使用 nuxt build 命令和环境变量 NITRO_PRESET=netlify-edge 在 Netlify 边缘函数上启用边缘侧渲染。

值得注意的是,当你使用边缘侧渲染结合路由规则时,可以使用混合渲染(Hybrid Rendering)。

你可以探索一些在上述提到的平台上部署的开源示例项目,以获取更多关于如何实现边缘侧渲染的实践知识。