Learn Nuxt with a Collection of 100+ Tips!

渲染模式

了解 Nuxt 中可用的不同渲染模式。

Nuxt 支持不同的渲染模式,包括通用渲染客户端渲染,但还提供了混合渲染以及在CDN边缘服务器上渲染应用程序的可能性。

浏览器和服务端都可以解释 JavaScript 代码来将 Vue.js 组件转换为 HTML 元素。这个步骤称为渲染(rendering)。Nuxt 支持通用(universal)和客户端(client-side)两种渲染方式。我们将分别讨论这两种方法的优势和缺点。

默认情况下,Nuxt 使用通用渲染来提供更好的用户体验、性能以及优化搜索引擎索引,但你可以在配置文件中一行配置中切换渲染模式。

通用渲染

当浏览器请求启用了通用(服务器端 + 客户端)渲染的 URL 时,服务器会向浏览器返回一个完全渲染的 HTML 页面。无论页面是预先生成并缓存,还是即时渲染,Nuxt 在某个时刻都会在服务器环境中运行 JavaScript(Vue.js)代码,生成一个 HTML 文档。与客户端渲染不同,用户可以立即获取到应用程序的内容,这个过程类似于传统服务器端渲染(SSR),如 PHP 或 Ruby 应用程序所执行的那样。

为了不失去客户端渲染方法的好处,如动态界面和页面过渡,浏览器(客户端)会在 HTML 文档下载后,在后台加载服务器上运行过的 JavaScript 代码。浏览器再次解释它(这就是所谓的通用渲染),Vue.js 控制文档并启用交互性。

使静态页面在浏览器中变得动态的过程称为“水合”(hydration)。

通用渲染允许 Nuxt 应用程序在保持客户端渲染好处的同时,提供快速的页面加载时间。此外,因为内容已经在 HTML 文档中,爬虫可以直接索引它,不需要额外的资源。

当 HTML 文档加载时,用户可以访问静态内容。水合过程随后允许页面的交互性

服务器端渲染的优点:

  • 性能:用户可以立即访问页面的内容,因为浏览器可以比 JavaScript 生成内容更快地显示静态内容。同时,Nuxt 保留了 web 应用程序的交互性,一旦水合过程发生。
  • 搜索引擎优化(SEO):通用渲染将页面的整个 HTML 内容交付给浏览器,就像传统的服务器应用程序那样。网站爬虫可以直接索引页面的内容,这使得通用渲染成为快速索引内容的理想选择。

服务器端渲染的缺点:

  • 开发限制:服务器和浏览器环境不提供相同的 API,编写可以在两个环境下无缝运行的代码可能很棘手。幸运的是,Nuxt 提供了指南和特定的变量来帮助你判断代码是在哪里执行的。
  • 成本:为了即时渲染页面,服务器需要运行。这增加了类似传统服务器的月度成本。然而,通过使用混合渲染降低了服务器调用,浏览器在客户端导航时接管了处理。通过利用边缘侧渲染,成本降低是可能的。

通用渲染非常灵活,几乎可以适应任何用例,尤其是对于任何内容导向的网站来说,是一个很好的选择:博客、营销网站、作品集、电子商务网站和市场平台

Vue 文档中了解更多关于编写没有水合错误的 Vue 代码的例子。
当你导入一个依赖于浏览器 API 并具有副作用的库时,确保只调用客户端组件中的导入。打包器不会树摇动模块包含副作用的导入。

客户端渲染

默认情况下,传统的 Vue.js 应用程序在浏览器(或客户端)中渲染。然后,Vue.js 在浏览器下载并解析所有包含生成当前界面指令的 JavaScript 代码后,生成 HTML 元素。

用户必须等待浏览器下载、解析和执行 JavaScript 才能看到页面的内容

客户端渲染的优点:

  • 开发速度:在完全客户端的情况下工作,我们不需要担心代码的服务器兼容性,例如使用仅浏览器 API,如window对象。
  • 更便宜:运行服务器增加了基础设施的成本,因为您需要在支持 JavaScript 的平台上运行。我们可以使用任何静态服务器托管仅客户端应用程序,包括 HTML、CSS 和 JavaScript 文件。
  • 离线:因为代码完全在浏览器中运行,所以在互联网不可用时它仍然可以很好地工作。

客户端渲染的缺点:

  • 性能:用户必须等待浏览器下载、解析和运行 JavaScript 文件。这取决于下载的网络部分和用户的设备解析和执行部分,这可能会花费一些时间并影响用户的体验。
  • 搜索引擎优化(SEO):通过客户端渲染交付的内容索引和更新需要比服务器渲染的 HTML 文档更长的时间。这与我们讨论的性能缺点相关,因为在第一次尝试索引页面前,搜索引擎爬虫不会等待界面完全渲染。在你的内容快速显示和更新在搜索结果页面上,纯客户端渲染的内容会花更多的时间。

客户端渲染是构建高度交互的 web 应用程序的好选择,这些应用程序不需要索引,或者用户经常访问。它可以利用浏览器缓存跳过下载阶段,如SaaS、后端办公室应用程序或在线游戏

你可以在你的nuxt.config.ts中使用 Nuxt 启用纯客户端渲染:

nuxt.config.ts
export default defineNuxtConfig({
  ssr: false
})
如果你确实使用了 ssr: false,你应该在 ~/app/spa-loading-template.html 中放置一个 HTML 文件,其中包含一些 HTML,你想在应用被水合之前渲染一个加载屏幕。
Read more in SPA 加载模板.
观看 Alexander Lichter 关于**用 Nuxt 构建一个纯 SPA 应用!?**的视频。

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

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

如果你使用纯客户端渲染,那么这可能是不必要的。你可能只需要一个 index.html 文件,加上 200.html404.html 回显,你的静态网络主机可以在所有请求上提供这些文件。

为了实现这一点,我们可以在 Nuxt 钩子nuxt.config.ts 中更改如何预渲染路由:

nuxt.config.ts
export default 
defineNuxtConfig
({
hooks
: {
'prerender:routes' ({
routes
}) {
routes
.
clear
() // 不要生成任何路由(除了默认的)
} }, })

这将生成三个文件:

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

200.html404.html 可能对你的托管提供商有用。

混合渲染

混合渲染允许为路由使用不同的缓存规则,使用路由规则(Route Rules),并决定服务器应该如何响应给定 URL 的新请求。

以前,Nuxt 应用程序的每个路由/页面和服务端必须使用相同渲染模式,无论是通用模式还是客户端模式。在某些情况下,一些页面可以提前生成,而其他页面应该仅在客户端渲染。例如,想象一个内容网站,有一个管理部分。每个内容页面应该主要是静态的,在生成后生成一次,但管理部分需要登录,更像是动态应用。

Nuxt 包括路由规则和混合渲染支持。使用路由规则,您可以为一组 Nuxt 路由定义规则,更改渲染模式或根据路由分配缓存策略!

Nuxt 服务器将自动注册相应的中间件和用 Nitro 缓存层包装路由。

nuxt.config.ts
export default 
defineNuxtConfig
({
routeRules
: {
// Homepage pre-rendered at build time '/': {
prerender
: true },
// Products page generated on demand, revalidates in background, cached until API response changes '/products': {
swr
: true },
// Product pages generated on demand, revalidates in background, cached for 1 hour (3600 seconds) '/products/**': {
swr
: 3600 },
// Blog posts page generated on demand, revalidates in background, cached on CDN for 1 hour (3600 seconds) '/blog': {
isr
: 3600 },
// Blog post page generated on demand once until next deployment, cached on CDN '/blog/**': {
isr
: true },
// Admin dashboard renders only on client-side '/admin/**': {
ssr
: false },
// Add cors headers on API routes '/api/**': {
cors
: true },
// Redirects legacy urls '/old-page': {
redirect
: '/new-page' }
} })

路由规则

你可以使用以下属性:

  • redirect: string - 定义服务器端重定向。
  • ssr: boolean - 禁用应用程序部分服务端渲染 HTML,并使用 ssr: false 使它们仅在浏览器中渲染。
  • cors: boolean - 自动添加跨域标头,使用 cors: true - 你可以使用 headers 覆盖输出。
  • headers: object - 为你的网站的某些部分添加特定标头 - 例如,你的资产。
  • swr: number | boolean - 向服务器响应添加缓存标头,并在服务器或反向代理上缓存它,配置 TTL(生存时间)。当 TTL 过期时,缓存的响应将被发送,同时页面将在后台重新生成。如果设置为 true,将会添加一个 stale-while-revalidate 标头,没有最大年龄。
  • isr: number | boolean - 行为与swr相同,除了我们能够将内容添加到 CDN 缓存(目前 Netlify 或 Vercel)。如果使用 true,内容在 CDN 上一直持续到下一次部署。
  • prerender: boolean - 预渲染路由在构建时并包含在您的构建中作为静态资产。
  • experimentalNoScripts: boolean - 禁用 Nuxt 脚本和 JS 资源提示的渲染,用于你的网站的某些部分。
  • appMiddleware: string | string[] | Record<string, boolean> - 允许你为 Vue 应用部分的你的应用程序中的页面路径定义应该或不应该运行的中间件。

在可能的情况下,路由规则将自动应用到你的部署平台的本地规则,以获得最佳性能(目前 Netlify 和 Vercel 支持)。

注意混合渲染在使用nuxt generate命令时不可用。

示例:

Nuxt Vercel ISR

一个使用混合渲染部署在 Vercel 上的 Nuxt 应用程序示例。

边缘侧渲染

边缘侧渲染(ESR)是 Nuxt 引入的一个强大特性,它允许你在用户的边缘服务器上更接近地渲染你的 Nuxt 应用程序,通过内容分发网络(CDN)的边缘服务器。通过利用 ESR,你可以确保更好的性能和减少延迟,从而提供增强的用户体验。

通过 ESR,渲染过程被推送到网络的“边缘”——CDN 的边缘服务器。请注意,ESR 更多地是一个部署目标,而不是实际的渲染模式。

当请求页面时,请求不会直接到达原始服务器,而是被最近的边缘服务器拦截。这个服务器生成页面的 HTML,并将其回传给用户。这个过程最小化了数据必须传输的物理距离,减少了延迟并更快地加载页面

边缘侧渲染是可能的,因为 Nitro服务器引擎,驱动 Nuxt 3。它提供了跨平台支持,包括 Node.js、Deno、Cloudflare Workers 等等。

目前可以在以下平台上使用 ESR:

注意,使用 ESR 时,混合渲染可以是有效的,并且可以使用路由规则。

你可以探索一些部署在上面提到的平台上的开源示例:

Nuxt Todos Edge

一个带用户认证、SSR 和 SQLite 的待办事项应用程序。

Atinotes

一个基于 Cloudflare KV 的可编辑网站,具有通用渲染。