用户说页面卡但 Lighthouse 全绿?今天把「真实感受」和「跑分」的差距彻底说清楚了

写过三年性能优化,你可能也有过这个经历:Lighthouse 跑了个 95 分,SEO 评分全绿,团队庆祝发版——然后用户说「页面卡死了」。你懵了,测试环境明明不卡,怎么到用户手里就卡了?

这不是你的代码有问题,是 Lighthouse 本身就不是测「真实用户感受」的。

Lighthouse 是实验室数据,不是真实数据

Lighthouse 跑的是一场模拟考试:固定机型(假设是中端 Android 机)、固定网络(假设是 4G 限速)、空缓存冷加载。它测的是「在这个固定环境下你做得怎么样」,而不是「你的真实用户实际上体验到了什么」。

真实用户的运行环境天差地别。有人用 iPhone 16 Pro Max 跑 Safari,有人用三年前的红米在地铁里刷你的页面。有人 Wi-Fi 满格,有人信号只有两格还开着 VPN。你的 Lighthouse 跑分可能只是「照顾好了中位数用户」,但还有一半用户体验根本没被测到。

真实用户感受到的,和 Lighthouse 告诉你的,完全是两回事

举一个真实场景:你的 LCP 目标是 2.5 秒以内,Lighthouse 给你报告 1.8 秒,全绿。但你的真实用户里,有 30% 的人在 4G 弱网下打开页面,LCP 是 4.5 秒。这 30% 的人不会去跑 Lighthouse,他们只会觉得「这个网站好慢」,然后关掉。

差距来自哪里?Lighthouse 测试的是空缓存首次加载,而真实用户里大量是回访用户——他们的缓存行为和首次加载完全不同。你优化的关键路径(preload、prefetch)只对首次加载有效,对回访用户几乎无效,但 Lighthouse 的报告里根本不会告诉你这一点。

Performance API 把真实数据补上了

Lighthouse 解决不了的问题,Performance API 可以补。

Chrome 提供了一套完整的性能数据采集 API,你可以把它接进自己的监控系统,实时看到真实用户的性能分布:

// 采集真实用户 LCP 数据
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // 上报到你的监控系统
    reportData({
      metric: "LCP",
      value: entry.startTime,
      element: entry.element?.tagName,
      url: location.href,
      // 带上真实上下文
      connection: navigator.connection?.effectiveType,
      deviceMemory: navigator.deviceMemory,
    });
  }
});
observer.observe({ type: "largest-contentful-paint", buffered: true });

navigator.connection 告诉你用户真实网络类型(4G/3G/2G),navigator.deviceMemory 告诉你设备内存档位。结合这些上下文,你才能知道「是网络慢还是代码慢」,而不是笼统地看一个平均分。

INP 的真实监控更重要

Lighthouse 里测的是 FID(首次输入延迟),但 2024 年之后 Chrome 已经把 INP(Interaction to Next Paint)作为主要交互响应指标。INP 衡量的是「用户所有交互中,响应最慢的那一次」,更能反映真实体验中的卡顿感。

INP 的问题在于它必须在真实用户环境里测——你没法模拟用户在页面上点哪个按钮、触发哪个弹层。只能用 PerformanceObserver 实时采集:

// 采集真实 INP 数据
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.interactionId) {
      reportData({
        metric: "INP",
        value: entry.duration,
        interactionType: entry.name,
      });
    }
  }
});
observer.observe({ type: "event", durationThreshold: 100, buffered: true });

下一步:怎么用这些数据做真实优化

拿到真实数据之后,你才能做对的事。

第一步,按网络类型分层看指标。如果 3G 用户的 LCP 是 4 秒,但 4G 用户是 1.5 秒,那问题不在代码,在资源体积和加载策略。把非首屏资源延迟加载、把图片切成 WebP、把关键 CSS 内联——这些改动对 3G 用户提升巨大,但 Lighthouse 的模拟环境测不出这个差距。

第二步,按设备内存档位看 JS 执行时间。navigator.deviceMemory 低档位设备跑你的大型框架可能天然就慢,这不是代码质量问题,是技术选型问题。真实数据会告诉你「要不要拆包」。

第三步,设定基于真实数据的性能预算。Lighthouse 给你的是实验室达标,真实用户 P75 达标才是目标。Google 的 CrUX 数据可以给你真实用户的 CrUX 报告,但它是历史数据;Performance API 才是实时的。

一句话总结:Lighthouse 是考试,Performance API 才是成绩单。

考试考得好,不代表真的学会了;跑分跑得高,不代表用户不卡。把 Performance API 接进监控,看到真实用户的 P75/P90 数据,你才知道性能优化这件事真正做到位没有。

下一步行动:今天就把 PerformanceObserver 接进你的监控系统,三个指标(LCP/INP/CLS)加上 navigator.connectiondeviceMemory 两个上下文维度,数据跑一周,你会看到很多 Lighthouse 永远看不到的东西。

评论区

0 条评论

登录后可评论。

阿速·性能优化 412 阅读