质量评估实战:从指标设计到落地优化的完整指南

❤贝贝 优化 阅读 2,086
赞 26 收藏
二维码
手机扫码查看
反馈

前端质量评估,我为啥最终只用 Lighthouse + 自定义规则

最近团队搞了一波性能优化,老板要求“可量化、可追踪、能进 CI”,于是我们开始折腾各种前端质量评估方案。市面上主流的就那么几个:Lighthouse、WebPageTest、自建 Puppeteer 脚本、还有些花里胡哨的商业工具。折腾了两周后,我基本确定了自己的主力方案——Lighthouse + 一套自定义规则。下面说说我踩过的坑和真实感受。

质量评估实战:从指标设计到落地优化的完整指南

谁更灵活?谁更省事?

先说结论:如果你不是做大型 CDN 性能压测,或者需要跨地域测速,别碰 WebPageTest。它功能确实强,但配置复杂、本地跑起来慢、CI 集成反人类。我试过在 GitHub Actions 里跑它的 Docker 镜像,光网络超时就调了三天,最后放弃。

Lighthouse 就舒服多了。Chrome DevTools 里点一下就能出报告,命令行也简单:

npx lighthouse https://jztheme.com/page --output json --output-path report.json

而且它直接集成进 CI 特别稳。我写了个小脚本,每次 PR 合并前跑一次,分数低于 80 直接 fail。开发们一开始抱怨,后来发现改几行 CSS 就能提分,反而上瘾了。

至于自建 Puppeteer 脚本?除非你有非常特殊的指标(比如“首屏是否包含特定 DOM 元素”),否则真没必要。Lighthouse 的审计项已经覆盖了 90% 的场景,自己写容易漏边界情况,还得多维护一套代码。

核心代码就这几行,但坑不少

很多人以为 Lighthouse 只能跑默认报告,其实它支持自定义审计(custom audits)和自定义 gatherers。我加了个规则:检测页面是否加载了非必要的第三方脚本(比如某个埋点 SDK 在非生产环境也加载了)。

实现起来不难,关键代码如下:

// custom-audit.js
const { Audit } = require('lighthouse');

class UnnecessaryThirdPartyAudit extends Audit {
  static get meta() {
    return {
      id: 'unnecessary-third-party',
      title: 'Avoid unnecessary third-party scripts',
      failureTitle: 'Found unnecessary third-party scripts',
      description: 'These scripts are not needed in current environment.',
      requiredArtifacts: ['devtoolsLogs', 'URL'],
    };
  }

  static async audit(artifacts, context) {
    const devtoolsLog = artifacts.devtoolsLogs.defaultPass;
    const requests = await context.driver.getNetworkRecords(devtoolsLog);
    const badUrls = requests
      .filter(r => r.url.includes('analytics-sdk') && !context.settings.environment?.includes('prod'))
      .map(r => r.url);

    return {
      score: badUrls.length === 0 ? 1 : 0,
      details: {
        type: 'table',
        headings: [{ key: 'url', itemType: 'url', text: 'URL' }],
        items: badUrls.map(url => ({ url })),
      },
    };
  }
}

然后在配置里挂上:

// lighthouse-config.js
module.exports = {
  extends: 'lighthouse:default',
  audits: ['path/to/custom-audit.js'],
  settings: {
    environment: process.env.NODE_ENV,
  },
};

看起来挺美,但这里我踩了好几次坑:

  • 第一次没处理 devtoolsLogs 的异步加载,直接报错;
  • 第二次忘了在 CI 里传 NODE_ENV,导致测试环境也误判;
  • 最头疼的是,Lighthouse 的 gatherer 和 audit 生命周期文档写得特别模糊,调试全靠 console.log + 猜。

不过一旦跑通,后续维护成本很低。现在这个规则每天帮我们拦住好几次“不小心把调试脚本带上线”的事故。

性能对比:差距比我想象的大

我拿三个方案对同一个页面跑了 10 次取平均值(本地 Mac M1,无网络干扰):

  • Lighthouse CLI:平均 8.2 秒
  • WebPageTest(本地 Docker):平均 22 秒
  • 自建 Puppeteer 脚本(只测 FCP + LCP):平均 5.1 秒

WebPageTest 慢得离谱,主要是它默认要录屏、截图、生成 waterfall 图,这些在 CI 里根本用不上。Lighthouse 虽然比纯 Puppeteer 慢,但多出来的 3 秒换来的是完整的可访问性、SEO、最佳实践评分——值了。

另外,Lighthouse 的分数波动比想象中大。同一页,有时 85,有时 78。后来发现是 Chrome 启动时内存占用不同导致的。解决办法是在 CI 里固定 CPU throttle 和 network conditions:

npx lighthouse https://jztheme.com/page 
  --throttling-method=provided 
  --cpu-throttling-rate=4 
  --output json

加了这俩参数后,分数稳定在 ±2 分内,够用了。

我的选型逻辑

我现在的工作流是这样的:

  • 日常开发:DevTools 里手动跑 Lighthouse,快速看问题;
  • PR 合并前:CI 自动跑带自定义规则的 Lighthouse,分数 & 自定义项双校验;
  • 线上监控:用 CrUX(Chrome User Experience Report)看真实用户数据,Lighthouse 只作参考。

为什么不用商业工具?像 SpeedCurve、Calibre 这些确实界面好看,但价格贵,而且很多功能我们用不到。Lighthouse 开源免费,还能深度定制,性价比太高。

当然,Lighthouse 也有硬伤:它测的是“实验室数据”,和真实用户感受可能有偏差。比如它模拟的 4G 网络,实际用户可能用的是信号差的 5G。所以我会结合 RUM(Real User Monitoring)数据交叉验证,但那是另一个话题了。

总之,对于大多数中小型项目,Lighthouse + 少量自定义规则 是最平衡的选择——省事、灵活、免费,还能进 CI。别一上来就搞复杂方案,先把基础打牢。

结尾碎碎念

以上是我踩坑后的总结,希望对你有帮助。其实前端质量评估没有银弹,关键看团队能不能坚持跑、能不能根据结果行动。我见过太多团队跑完 Lighthouse 报告就扔一边,那还不如不跑。

如果你有更好的自定义审计写法,或者踩过其他坑,欢迎评论区交流。这个技巧的拓展用法还有很多(比如结合 Sentry 做异常上报联动),后续会继续分享这类博客。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论