惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
罗磊的独立博客
博客园 - 司徒正美
Last Week in AI
Last Week in AI
The Cloudflare Blog
大猫的无限游戏
大猫的无限游戏
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
The GitHub Blog
The GitHub Blog
宝玉的分享
宝玉的分享
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
小众软件
小众软件
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
B
Blog
博客园 - 【当耐特】
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell

前端开发

前端设计的困惑 - V2EX 前端联调不用再求后端:我做了个 Chrome DevTools 网络拦截工具 SuperNetDev - V2EX 不知道有没有人想尝试一下没有 Tailwind CSS 的 shadcn 组件样式注册表 - V2EX SolidJS 2.0 RC 了,简直艺术品 - V2EX 万能的 AI,有什么实现高保真 UI 的途径吗? taro 还有人用吗? 是不是要黄了,官网证书到期了都没人管,而且物料市场都打不开了 Better Auth 也被 Vercel 收购了 “前端大神在大厂里写广告”是真的吗? V2EX › 登录 前端转 ai-agent 有什么好的课程么 angular21 好用吗? 全 AI 开发安卓 ios 双端行业内 BOSS 直聘 APP,求技术方案 前端如何学习 AI?我发现所有文章都是教你怎么写个 agent 或者讲 agent 实现原理什么的,就没有能在日常工作中 提效的吗?比如 skill 怎么搞。怎么在工作中使用各种技巧 3D 全域高清一张图制作,有没有懂行的高手会啊!需求放在下面了 开源了一个 Notion/飞书 风格的编辑器 大家用 uniappx 开发的时候,都选择什么 ui 框架呢 探索了一下 Agent Native 的 UI 应该怎么做,附带项目链接 开发抖音 pc 网页的 100%都是些草包。 Solid 作者重新審視 React 做對了的兩件事,以及將會在 Solid 2.0 採用 有大佬认识这是哪个图标库吗? 请教关于不发版动态更新 APP 的 LOGO 方案 关于如何正确的在 React 或 Vue 中使用链接 逆向专题:对于 web 端采用 wasm+protobuf 的架构,还有逆向的可能性吗 AI 时代你们是怎么开发前端页面的? 有大佬在 qiankun 中结合联邦模块的吗 Tailwind CSS 在本周裁员 75% 原因是受 AI 冲击 有没有前端组件实现变量是个标签,其他字是黑色文字的组件库 1.5 小时用 ai 写了个 web 恐怖小游戏 30USD 月度开发预算,前端 er 都在用什么 AI 编程工具? 现在有些网站还要求 ie 访问
Next.js 多语言路由性能优化:从 5.8s LCP 到极致体验
hazellin549 · 2026-02-20 · via 前端开发

为什么你的英文版比中文版慢 3 倍?


01 一个诡异的性能问题

上周,我在检查网站的性能报告时,发现了一个诡异的现象:

语言版本 LCP CLS
中文 (默认) 2.3s ✅ 0.06 ✅
英语 /en/ 5.8s ❌ 0.68 ❌

同一套代码,同一个页面,为什么英文版比默认语言慢了整整 2.5 倍?

这篇文章记录我的排查过程和最终解决方案。


02 先搞清楚 LCP 是什么

LCP (Largest Contentful Paint) 是 Core Web Vitals 的核心指标之一。

简单说,它测量的是:页面主要内容出现的时间

Google 的标准是:

  • < 2.5s — 良好
  • ⚠️ 2.5s - 4s — 需要改进
  • > 4s — 较差

我的英文版 5.8s ,妥妥的「红牌警告」。


03 第一个嫌疑人:缓存策略

在 Next.js 的多语言路由中,默认语言和非默认语言的处理逻辑是不同的。

默认语言: example.com/product
非默认语言: example.com/en/product

我检查了 CDN 缓存命中率:

路由 缓存命中率
/product 89% ✅
/en/product 31% ❌

问题出现了:非默认语言的缓存命中率低得可怜。

原因分析

Next.js 默认生成的 Cache-Control 头对于动态路由是这样的:

Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate

而我的多语言路由 /[locale]/... 被识别为「动态路由」,导致 CDN 几乎不缓存。

解决方案

next.config.js 中显式配置缓存策略:

async headers() {
  return [
    {
      source: '/:locale(en|es|fr)/:path*',
      headers: [
        {
          key: 'Cache-Control',
          value: 'public, s-maxage=3600, stale-while-revalidate=86400',
        },
      ],
    },
  ];
}

效果:缓存命中率从 31% 提升到 **85%**。


04 第二个嫌疑人:关键资源预加载

优化缓存后,LCP 从 5.8s 降到了 3.9s ,但还是不达标。

Lighthouse 报告给了一个提示:

⚠️ Preload key requests
Fonts and critical CSS are not being preloaded

我检查了页面的资源加载顺序:

1. HTML 文档
2. 等待解析...
3. 发现 CSS 引用
4. 下载 CSS
5. 发现字体引用
6. 下载字体
7. 渲染文字 ← LCP 发生在这里

问题是:字体要等到 CSS 加载完才开始下载,形成了瀑布流。

解决方案

<head> 中添加预加载标签:

<Head>
  {/* 预加载关键字体 */}
  <link
    rel="preload"
    href="/fonts/inter-variable.woff2"
    as="font"
    type="font/woff2"
    crossOrigin="anonymous"
  />
  
  {/* 预加载关键 CSS */}
  <link
    rel="preload"
    href="/_next/static/css/app.css"
    as="style"
  />
</Head>

效果:LCP 从 3.9s 降到 2.7s


05 第三个嫌疑人:图片加载

还差 0.2s 才能达到 2.5s 的「良好」标准。

Lighthouse 又给了提示:

⚠️ Largest Contentful Paint element
<img src="/hero-banner.png" ...>

原来 LCP 元素是首屏的大图。

问题

图片使用了 Next.js 的 <Image> 组件,默认是懒加载的:

<Image src="/hero-banner.png" ... />
// 默认 loading="lazy"

但对于首屏图片,懒加载反而拖慢了显示速度。

解决方案

对 LCP 元素禁用懒加载,并添加 priority 属性:

<Image
  src="/hero-banner.png"
  priority  // 关键!
  loading="eager"
  ...
/>

效果:LCP 从 2.7s 降到 2.2s


06 CLS 问题:页面为什么在「抖动」?

解决完 LCP ,再看 CLS 。

CLS (Cumulative Layout Shift) 测量的是:页面元素的意外位移

我的英文版 CLS 是 0.68 ,而标准是 < 0.1 。

打开页面慢动作回放,发现了两个问题:

问题 1:字体加载导致的「闪烁」(FOUT)

页面先用系统字体渲染,字体加载完后「闪」一下变成自定义字体。

由于两种字体的 metrics 不同,文字位置发生偏移。

解决方案:使用 font-display: optional

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-variable.woff2') format('woff2');
  font-display: optional; /* 如果字体没及时加载,就不换了 */
}

问题 2:图片没有指定尺寸

// ❌ 错误写法
<img src="/card.png" />

// ✅ 正确写法
<img src="/card.png" width={300} height={400} />

Next.js 的 <Image> 组件会自动处理这个问题,但我有几个地方用了原生 <img>

效果:CLS 从 0.68 降到 0.04


07 优化前后对比

指标 优化前 优化后 改善
LCP 5.8s ❌ 2.2s ✅ -62%
CLS 0.68 ❌ 0.04 ✅ -94%
缓存命中率 31% 85% +174%
Lighthouse 52 91 +75%

08 核心经验总结

多语言路由的性能优化,核心要点:

🎯 缓存策略

非默认语言路由容易被当作「动态页面」而跳过缓存。显式配置 Cache-Control

🎯 预加载关键资源

字体和关键 CSS 形成瀑布流是 LCP 的常见杀手。<link rel="preload"> 打破瀑布。

🎯 LCP 元素优先加载

首屏图片不要懒加载。priority 属性告诉 Next.js 这是关键资源。

🎯 防止布局偏移

  • 图片必须指定尺寸
  • 字体使用 font-display: optionalswap + 预加载
  • 避免动态插入内容到首屏

09 一个容易忽略的细节

最后分享一个容易忽略的点:

不同语言版本的字体 metrics 可能不同。

比如中文字体通常比英文字体更高,如果你用同一套 CSS ,line-height 可能导致不同语言的布局高度不一致。

我的做法是为每种语言定义 bodyfont-family 后备栈:

/* 英语/西班牙语 */
body[lang="en"], body[lang="es"] {
  font-family: 'Inter', system-ui, sans-serif;
}

/* 中文 */
body[lang="zh"] {
  font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', sans-serif;
}

10 写在最后

性能优化是一个「挤牙膏」的过程:

  • 第一轮优化(缓存):5.8s → 3.9s
  • 第二轮优化(预加载):3.9s → 2.7s
  • 第三轮优化(图片):2.7s → 2.2s

每一轮看起来改动不大,但累积下来效果惊人。

如果你的多语言网站也有性能问题,不妨按这个顺序排查:

  1. 缓存是否生效?
  2. 关键资源是否预加载?
  3. LCP 元素是否优先加载?
  4. 有没有布局偏移?

希望这篇文章对你有帮助!