质量评估实战:从指标设计到落地优化的完整指南
前端质量评估,我为啥最终只用 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 做异常上报联动),后续会继续分享这类博客。

暂无评论