渲染模式
Nuxt支持不同的渲染模式,包括通用渲染,客户端渲染,还提供了混合渲染和在CDN边缘服务器上渲染应用程序的可能性。
浏览器和服务器都可以解释JavaScript代码,将Vue.js组件转换为HTML元素。这个过程被称为渲染。Nuxt同时支持通用渲染和客户端渲染。这两种方法都有优点和缺点,我们将一一介绍。
默认情况下,Nuxt使用通用渲染以提供更好的用户体验、性能优化和搜索引擎索引优化,但你可以在一行配置中切换渲染模式。
通用渲染
当浏览器请求启用了通用(服务器端+客户端)渲染的URL时,服务器将一个完整渲染的HTML页面返回给浏览器。无论页面是预先生成并缓存的,还是即时渲染的,在某个时刻,Nuxt都在服务器环境中运行了JavaScript(Vue.js)代码,生成了一个HTML文档。用户立即获得我们应用程序的内容,与客户端渲染相反。这一步类似于PHP或Ruby应用程序执行的传统服务器端渲染。
为了不失去客户端渲染方法的好处,如动态界面和页面过渡效果,客户端(浏览器)在下载完HTML文档后会在后台加载运行在服务器上的JavaScript代码。浏览器再次解释它(因此称为通用渲染),Vue.js接管文档并启用交互性。
在浏览器中使静态页面具有交互性被称为“水合”。
通用渲染使Nuxt应用程序能够快速加载页面,同时保留了客户端渲染的好处。此外,由于内容已经存在于HTML文档中,爬虫可以在没有额外开销的情况下对其进行索引。
服务器端渲染的好处:
- 性能:用户可以立即访问页面的内容,因为浏览器可以比JavaScript生成的内容更快地显示静态内容。同时,当水合过程发生时,Nuxt保留了Web应用程序的交互性。
- 搜索引擎优化:通用渲染将整个HTML内容作为经典服务器应用程序直接传递给浏览器。Web爬虫可以直接索引页面的内容,这使得通用渲染成为任何希望快速索引的内容的绝佳选择。
服务器端渲染的缺点:
- 开发约束:服务器和浏览器环境提供的API不同,编写可以在两个环境中无缝运行的代码可能会有些棘手。幸运的是,Nuxt提供了指导方针和特定的变量,帮助你确定代码在哪个环境中执行。
- 成本:为了即时渲染页面,服务器需要运行。这和任何传统服务器一样增加了每月的成本。然而,由于浏览器在客户端导航时接管了服务器调用,调用次数大大减少。通过利用边缘端渲染,可以实现成本的降低。
通用渲染非常灵活,几乎适用于任何用例,特别适合面向内容的网站:博客、营销网站、作品集、电子商务网站和市场。
客户端渲染
传统的Vue.js应用程序默认在浏览器(或客户端)中进行渲染。然后,Vue.js在浏览器下载和解析所有包含创建当前界面指令的JavaScript代码后,生成HTML元素。
客户端渲染的优点:
- 开发速度:在完全在客户端进行工作时,我们不必担心代码的服务器兼容性,例如,使用仅在浏览器中可用的API,如
window
对象。 - 成本较低:运行服务器会增加基础设施成本,因为需要在支持JavaScript的平台上运行。我们可以将仅客户端的应用程序托管在任何具有HTML、CSS和JavaScript文件的静态服务器上。
- 离线工作:因为代码完全在浏览器中运行,所以在网络不可用的情况下,它可以继续正常工作。
客户端渲染的缺点:
- 性能:用户必须等待浏览器下载、解析和运行JavaScript文件。根据下载部分的网络和解析和执行的用户设备的性能,这可能需要一些时间,并影响用户的体验。
- 搜索引擎优化:通过客户端渲染提供的内容进行索引和更新比使用服务器渲染的HTML文档需要更长的时间。这与我们讨论的性能缺点有关,因为搜索引擎爬虫不会等待界面在第一次尝试索引页面时完全渲染。纯客户端渲染将导致内容在搜索结果页面中显示和更新所需的时间更长。
客户端渲染适用于需要大量交互的Web应用程序,不需要索引或其用户频繁访问的应用程序。它可以利用浏览器缓存,在后续访问中跳过下载阶段,例如SaaS、后台应用程序或在线游戏。
你可以在你的nuxt.config.ts
中启用仅客户端渲染:
export default defineNuxtConfig({
ssr: false
})
ssr: false
,你还应该在~/app/spa-loading-template.html
中放置一个HTML文件,其中包含你想要用于渲染加载屏幕的HTML。直到应用程序被水合之前,它将被渲染。混合渲染
混合渲染允许每个路由使用路由规则的不同缓存规则,并决定服务器如何响应给定URL的新请求。
以前,Nuxt应用程序和服务器的每个路由/页面必须使用相同的渲染模式,通用渲染或客户端渲染。在各种情况下,一些页面可以在构建时生成,而其他页面应该是客户端渲染的。例如,考虑一个具有管理部分的内容网站。每个内容页面应该是主要静态的,并且只生成一次,但管理部分需要注册并且更像是一个动态应用程序。
Nuxt 3包括了路由规则和混合渲染支持。使用路由规则,你可以为一组Nuxt路由定义规则,改变渲染模式或基于路由分配缓存策略!
Nuxt服务器将自动注册相应的中间件,并使用Nitro缓存层包装路由。
export default defineNuxtConfig({
routeRules: {
// 主页在构建时预渲染
'/': { prerender: true },
// 产品页面按需生成,后台自动重新验证
'/products/**': { swr: 3600 },
// 博客文章按需生成,直到下一次部署前持续有效
'/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: true
自动添加CORS头部,你可以通过覆盖headers
来自定义输出。headers: object
- 为你的站点的某些部分添加特定的头部,例如你的资源文件。swr: number|boolean
- 为服务器响应添加缓存头部,并在服务器或反向代理上缓存它,以配置的TTL(存活时间)进行缓存。Nitro的node-server
预设能够缓存完整的响应。当TTL过期时,将发送缓存的响应,同时在后台重新生成页面。如果使用true
,则添加了一个不带MaxAge的stale-while-revalidate
头部。isr: number|boolean
- 行为与swr
相同,除了我们能够将响应添加到支持此功能的CDN缓存中(目前支持Netlify或Vercel)。如果使用true
,内容将在CDN中持久存在,直到下一次部署。prerender:boolean
- 在构建时预渲染路由,并将其包含在你的构建中作为静态资源。experimentalNoScripts: boolean
- 禁用Nuxt脚本的渲染和JS资源提示,用于你站点的某些部分。
在可能的情况下,路由规则将自动应用于部署平台的本机规则,以实现最佳性能(当前支持Netlify和Vercel)。
nuxt generate
时,无法使用混合渲染。示例:
icon: i-simple-icons-github
title: Nuxt Vercel ISR
to: https://github.com/danielroe/nuxt-vercel-isr
target: _blank
ui.icon.base: text-black dark:text-white
在Vercel上部署的具有混合渲染的Nuxt应用程序示例。边缘端渲染
边缘端渲染(ESR)是Nuxt 3引入的一个强大功能,它允许通过内容交付网络(CDN)的边缘服务器在离用户更近的位置渲染你的Nuxt应用程序。通过利用ESR,你可以确保提供更好的性能和降低延迟,从而提供更好的用户体验。
使用ESR,渲染过程被推到了网络的“边缘” - CDN的边缘服务器。请注意,ESR更多是一个部署目标,而不是实际的渲染模式。
当发出对页面的请求时,请求不会直接发送到原始服务器,而是被最近的边缘服务器拦截。该服务器生成页面的HTML,并将其发送回用户。这个过程将数据需要传输的物理距离最小化,减少延迟并更快地加载页面。
边缘端渲染得益于Nitro,这是Nuxt 3的服务器引擎。它支持Node.js、Deno、Cloudflare Workers等多个平台。
目前可以利用ESR的平台有:
- Cloudflare Pages,使用git集成和
nuxt build
命令,无需任何配置。 - Lagon,使用
NITRO_PRESET=lagon npx nuxt build
命令。 - Vercel Edge Functions,使用
nuxt build
命令和NITRO_PRESET=vercel-edge
环境变量。 - Netlify Edge Functions,使用
nuxt build
命令和NITRO_PRESET=netlify-edge
环境变量。
请注意,当使用路由规则时,混合渲染可以与边缘端渲染一起使用。
你可以探索部署在上述某些平台上的开源示例: