Prismic 优化检测 免费在线检测工具
首页 › 笔记 › 为什么各种平台的页面在 PageSpeed 上都分数难看——以及为什么"分数"本身就是错的指标

为什么各种平台的页面在 PageSpeed 上都分数难看——以及为什么"分数"本身就是错的指标

这几年我一直在做 Next.js、Prismic、Shopify、WordPress 站的性能。这篇文章是我弄明白的一件事:为什么这些数字永远对不上——以及我最后到底报的是哪几个数。


#几乎每个项目上,我都会被问同一个问题

有客户问我:"为什么我们的分数这么低?"

那个站用起来是快的。看起来也快。我自己笔记本上跑 Lighthouse,98 分。

PageSpeed Insights 说 71 分。

两个数字都没错。但有两件事没人告诉过他:

  1. 这两台仪器测的根本不是同一件事。
  2. 分数不是你网站的属性,它是一次读数——在某台机器上、某个网络下、某一刻取的。

第二条,是我现在会先说出口的那一条。


#一、你测的到底是什么

本地 Chrome 的 Lighthouse 和 PageSpeed Insights,有四个变量在同时变化:

  • 网络。 本地:你家宽带,通常还带缓存。PageSpeed:固定 Slow 4G。
  • CPU。 本地:你自己的机器。PageSpeed:4 倍 CPU 节流。
  • 缓存。 本地:很容易保持热缓存。PageSpeed:每次冷启动。
  • 地理。 本地:通常离 CDN 很近。PageSpeed:Google 机房 → 你的主机,TTFB 更差。

同一个页面,98 和 71。这个差距不是哪个工具的 bug——是四个变量同时在变,而只有一个是你的代码。

我的做法:我报任何一个数字,都会说清它是哪个工具、哪个配置跑出来的。缺了这个上下文的数字不是信息。


#二、我见过三种"测错了"

在 dev 服务器上测。 npm run dev 不压缩,还在跑热更新循环。我在一个生产环境 80 多分的页面上,测出过移动端 约 52 分。那不是基线,那是噪声。

在已经访问过的浏览器里测。 你的缓存替访客挡掉了他们必须付的代价。开无痕、关缓存,否则别信那个数。

测了一个已经被替换掉的部署。 你改了代码——但你测的 URL 是上一版构建。用预览部署的时候,这件事天天发生。

我的做法:动手之前,我先把工具、配置、URL、构建版本写下来。我被叫去修的"性能回退"里,有一半其实是这三种情况之一。


#三、为什么各种平台的页面分数都难看

我做的是四种技术栈,它们的坏法各不相同。但底层病因是同一个:

这些平台,每一个都允许"不是你写的代码"跑在你的关键路径上。

Shopify——第三方脚本主宰分数。 在 Shopify 上,主题很少是问题本身。预约、评论、客服、热图、像素——它们都是运行时注入,并且占着主线程。

我手上最清楚的一个例子:一个预约 App 从 Google CDN 拉 jQuery。弱网下那个请求变慢或直接失败,按钮就永远停在"Loading…"。修的地方不在 App 里,而在主题侧:

  • 把 jQuery 自托管进主题,在产品模板上提前加载
  • 对 App 的 CDN 加 preconnect
  • 关掉移动端挡住弹窗的吸底加购按钮
  • 修掉弹窗的 z-index 和滚动锁

而复现方式比修法更关键:那个"按钮消失"只在弱网下、从列表页跳进详情页时才出现。单独测列表页,什么都证明不了。

我的做法:Shopify 上我测那个"脚本真正注入的页面",而不是那个"方便测的页面"。

WordPress——插件堆积。 邮件、礼品卡、表单、支付,每一样都带自己的前端 JS 和 CSS,堆起来比谁预想的都快。缓存还是陷阱:登录态、购物车、结账页通常绕过缓存,所以两种状态我都测,并且说清报的是哪一种。

Next.js 和内容型站点——三个惯犯。 同一个资源被下载两次(一个只在手机显示的 <img> 加一个只在桌面显示的 <img>,同一个文件);一个 CSS background-image 要等样式表解析完才被发现;首屏包里的 JavaScript 太多。

我的做法:内容型站点我第一个问题永远是——LCP 那个元素,在初始 HTML 里能被发现吗? 我遇到的最慢的那些案例,答案都是"不能"。


#四、分数到底扣在哪

Lighthouse 10 的性能权重大致是:

  • TBT——约 30%。 主线程被长任务阻塞。
  • LCP——约 25%。 最大元素渲染太晚。
  • CLS——约 25%。 布局跳动。
  • FCP——约 10%。 首次内容绘制。
  • SI——约 10%。 视觉完整速度。

TBT 加 LCP,超过一半。 所以有人让我"修一下性能",我就做这两个,而且我会直接说出来。整周去抠 FCP 和 Speed Index,是在处理 20% 的问题。

而且我都在移动端做。桌面分数看起来都正常,正好把这些问题全遮住。


#五、两个到现在还会让人意外的点

纯色背景不算 FCP。 首次内容绘制需要真正的内容——文字、图片、渐变、SVG。整页只刷一个背景色,它就没有首绘,不管看起来多好看。

font-display: optional 能帮你赢下 CLS 和 LCP——在网速好的时候。而在慢网下,整次访问都会停在兜底字体上。在客户眼里那不是"我选的权衡",那是个 bug。


#六、不舒服的那部分,我现在会提前说

这是一个真实项目上的数字链,按顺序:

  • 本地宽带 Lighthouse:最高 98
  • PageSpeed Insights 移动端:71–75
  • 临时压缩图片:约 91——客户以"变模糊"为由否掉
  • 恢复高清图:稳定在 82–85

所以现在项目一开始我就把这句话说掉:

如果"不降画质、不改结构"是硬要求,移动端分数很少能锁在 90。

总得让一样东西:体积、动效,或者图片。我的工作就是告诉你我会放弃哪一样、代价是什么。如果没有人就这个达成一致,我们会永远为分数争论——而分数恰恰是那个取决于它在哪台机器上被测的数字。


#七、那我都报什么

我不再把分数当目标。它只是一个依赖环境的读数。

页面体积和 LCP 是页面本身的属性。 它们能跨环境走——Google 测和我测,是同一个值。所以我测这两个,给同一台机器上前后紧挨着测出来的对比。

分数告诉你:某台机器、某个网络,对你的页面是什么感觉。

页面体积和 LCP 告诉你:你的页面实际上是什么。


#八、三步,你自己就能验

  1. DevTools → Network → Img,刷新。 找最大的那张图,把文件的真实宽度和它实际显示的尺寸比一下。文件是渲染尺寸的 2–3 倍,你的第一个收益就在这——而且通常是最便宜的那个。
  2. 移动端 Lighthouse 跑三次,报中位数。 永远不要只跑一次。只跑一次等于抛硬币。
  3. 在你 HTML 里搜两个指向同一个文件的 <img> 标签。 那就是重复下载,修它不花钱。

#一句话版本

测生产环境,别测 dev 服务器。让 LCP 元素能被发现、只请求一次。把首屏的 JavaScript 和字体从关键路径上挪开。记住纯色不算 FCP。Shopify 的 App 要在它真正加载的那个页面测。在你向任何人承诺数字之前,先把画质上的取舍谈清楚。


我做内容驱动站点的前端——Next.js、Prismic、Shopify、WordPress——并且把结果测出来,而不是口头断言。想知道你的站是真的慢,还是只是被测坏了,把它丢进 prismicaudit.com,把结果发我。