性能优化与缓存
本教程共 50 篇 · 第 44 篇 · 更新于 2026-08-08 · 约 9 分钟阅读
本节目标:理解 Nuxt 自带的和靠模块获得的性能能力,掌握懒加载、缓存策略与常见性能陷阱,写出更快的 Nuxt 应用。
44-1
业界常用 Core Web Vitals 衡量体验:LCP(最大内容绘制,首屏主图多快出来)、CLS(布局抖动,页面会不会突然跳动)、INP(交互到下一次绘制,点击后多快响应)。Nuxt 的很多优化都是围绕这三项来的。优化前先量化,别凭感觉。
44-2
<NuxtLink> 不只是 <a> 的替身,它默认带「智能预取」:当链接进入视口(或滚动到附近),它会提前把目标页面的 JS 下载好,用户一点就秒开。
<template>
<NuxtLink to="/about">关于页</NuxtLink>
</template>
如果不想要「进视口就预取」,可以改成仅在交互时预取:
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: {
prefetchOn: {
interaction: true,
visibility: false,
},
},
},
},
})
Tip预取是「锦上添花」,不是必须。页面很多时,全部进视口就预取会多下载些 JS。对流量敏感的场景,用上面的
prefetchOn改成交互触发更稳妥。
44-3
给组件名加 Lazy 前缀,Nuxt 会动态导入它——只有真正用到时才下载代码,缩小首屏包体积:
<script setup lang="ts">
const show = ref(false)
</script>
<template>
<div>
<h1>山脉</h1>
<LazyMountainsList v-if="show" />
<button v-if="!show" @click="show = true">显示列表</button>
</div>
</template>
从 Nuxt 3.16 起还支持「懒激活(lazy hydration)」:组件先渲染但不急着变可交互,等它进入视口或浏览器空闲再激活:
<template>
<LazyMyComponent hydrate-on-visible />
</template>
对内容站、营销站,把预渲染、noScripts 路由规则、服务端组件和懒激活组合,可以做到「近乎零 JS」。
44-4
用 useFetch/useAsyncData 取数据,Nuxt 保证:服务端取过的数据,客户端激活时直接复用 payload,不会请求第二遍。这既是正确性问题,也是性能问题——少一次往返就快一截。
Note这就是为什么教程一直强调用 Nuxt 自带的数据获取,而不是裸
fetch。裸fetch在服务端、客户端各跑一次,既慢又容易 hydration 不匹配。
44-5
第 43 章讲过的 routeRules 就是缓存主力:swr/isr 让 Nitro 在边缘或内存里缓存渲染结果。对读多写少的页面,这是性价比最高的优化。
export default defineNuxtConfig({
routeRules: {
'/products/**': { swr: 3600 },
'/blog': { isr: 3600 },
},
})
44-6
除了内置特性,Nuxt 团队维护的核心模块专门解决「资源类」性能瓶颈:
@nuxt/image:<NuxtImg>自动转 WebP/AVif、按宽高压缩、生成响应式sizes、支持原生懒加载。首屏大图用loading="eager"+preload,次要图用loading="lazy"。
<template>
<NuxtImg src="/hero.jpg" format="webp" loading="eager" width="200" height="100" />
<NuxtImg src="/logo.jpg" format="webp" loading="lazy" width="200" height="100" />
</template>
@nuxt/fonts:自动优化字体、自托管,减少布局抖动(CLS),还能生成本地兜底字体。@nuxt/scripts:把第三方脚本(分析、地图、社交组件)封装成带 SSR 支持和类型安全的加载方式,避免它们拖垮 INP 和 LCP。
Tip图片往往是 LCP 的元凶。先优化首屏图(尺寸、格式、预加载),收益通常最大,比抠业务逻辑快得多。
44-7
优化要「先测后改」:
nuxi analyze:可视化生产包构成,看哪块体积最大、该拆分或懒加载。- Nuxt DevTools:Timeline(追踪渲染耗时)、Assets(看资源大小)、Render Tree(组件依赖)、Inspect(文件体积与求值时间)。
- Chrome DevTools:Performance 面板直接显示 LCP/CLS/INP;Lighthouse 跑综合审计给改进建议。
- PageSpeed Insights / WebPageTest:真实环境的移动/桌面体验报告。
44-8
- 插件滥用:插件在激活阶段运行,太多或太重会阻塞渲染。能写成组合式函数/工具函数的,就别做成插件。
- 无用代码/依赖:定期扫
package.json和没用到的工具,删掉就小一点。 - 忘了 Vue 自身的性能技巧:
shallowRef、v-memo、v-once在 Nuxt 里一样能用,别只盯着 Nuxt 专属优化。 - 不遵循团队约定:人多时各加各的模式容易冲突。建立统一规则(如组合式函数写法)比临时优化更持久。
- 一股脑全加载:页面没告诉浏览器加载顺序,结果所有东西同时下载。用渐进增强,核心内容先到,增强层随后。
Warning看到
nuxi analyze里一大块第三方库,别急着全删——先确认是不是「只用了其中一小部分」。只导入需要的子模块,往往比整包引入省出一大截体积。
44-9
Nuxt 3 与 Nuxt 4 的性能特性(NuxtLink 预取、懒加载、routeRules 缓存)一致。核心优化模块(image/fonts/scripts)跨版本通用。Nuxt 4 因 app/ 约定,资源与组件路径略有变化,但优化手段本身相同。
44-10
首屏(LCP)容易优化,但用户「点了一下多久才有反应」靠的是 INP。最典型拖累 INP 的是「主线程被长任务占住」:比如页面挂载时一口气算大量数据、或第三方脚本(聊天 widget、分析)抢主线程。对策:把重计算挪到 onMounted 之后、用 await nextTick() 拆开,或交给 Web Worker。
Tip先用 Chrome DevTools 的 Performance 面板录一段交互,看哪段脚本占了长任务(标红的长条)。先优化最粗的那根,比到处微调收益大。
44-11
Nuxt 自带预取、懒加载、数据复用,配合 routeRules 缓存和 image/fonts/scripts 三大模块,覆盖大部分性能场景。优化前先用 analyze/DevTools/Lighthouse 量化,避开插件滥用等陷阱。下一章进入测试。
44-7 性能监控与基准测试
优化不是一次性的工作,而是持续的过程。建立性能监控机制,定期测量关键指标,才能确保优化效果不退化。Web Vitals 是一组广泛使用的性能指标:LCP(最大内容绘制)衡量加载速度、FID(首次输入延迟)衡量交互响应、CLS(累积布局偏移)衡量视觉稳定性。
在 Nuxt 项目里,可以用 @nuxtjs/speed-insights 或第三方工具(如 Lighthouse CI)定期跑性能测试。把测试结果集成到 CI 流程里,如果某次提交导致性能明显下降,自动发出警告。
前端性能优化是一个大话题,但核心原则很简单:减少传输体积、减少请求次数、减少阻塞渲染的资源。Nuxt 的自动代码分割、资源哈希、按需加载等特性已经帮你做了很多优化,你需要关注的主要是业务层面的优化,如图片压缩、第三方脚本延迟加载等。
44-8 前端性能优化的检查清单
除了 Nuxt 框架本身提供的优化,前端层面还有很多可以做的事情。以下是一份实用的性能优化检查清单。
第一,图片优化:使用现代格式(WebP/AVIF)、提供响应式尺寸、启用懒加载。第二,JavaScript 优化:按需加载路由组件、延迟加载非关键第三方库、移除未使用的代码。第三,CSS 优化:提取关键 CSS 内联到 HTML、非关键 CSS 异步加载、移除未使用的样式规则。
第四,网络优化:启用 HTTP/2 多路复用、配置合理的缓存策略、使用 CDN 加速静态资源。第五,渲染优化:避免大的 DOM 节点、减少布局抖动、使用 CSS 动画代替 JavaScript 动画。逐项检查并落实这些优化,你的 Nuxt 应用性能会有质的提升。