如何将 Lighthouse CI 集成到 grunt 构建
解读
面试官问“如何把 Lighthouse CI 集成到 grunt 构建”,并不是想听“装个插件就行”。他要确认三件事:
- 你是否理解 Grunt 的任务调度机制(task、target、option、流程编排);
- 你是否熟悉 Lighthouse CI 的两种运行模式(CLI 与 Node API),并能权衡其优缺点;
- 你能否把性能卡点前置到 CI 阶段,并给出国内网络、私有仓库、权限、报告归档等工程化闭环方案。
回答时务必体现“任务拆分 → 插件选型 → 参数调优 → 报告消费 → 失败策略”五步闭环,让面试官听到“可落地、可回滚、可度量”。
知识点
- grunt-contrib-copy / grunt-contrib-clean:准备待测产物目录,保证 Lighthouse 扫描的是真实待上线文件而非源码。
- grunt-run / grunt-exec:在 Grunt 流程里无阻塞地调用 npx lhci autorun,并透传 token、config 路径等环境变量。
- LHCI 配置文件(lighthouserc.js):
– ci.collect.url:支持本地静态服务器地址,需与 grunt-contrib-connect 的端口随机化做联动;
– ci.assert.assertions:国内项目建议先关闭 uses-webp、unused-css-rules 等“外网 CDN”敏感断言,避免误报;
– ci.upload.target:若用 GitLab CI,需改target: ‘filesystem’,再配 grunt 任务把
.lighthouseci文件夹归档到artifacts/。 - 性能预算(budgets.json):与 grunt-perfbudget 做指标互补,但 LHCI 的 JSON 报告更利于后续数据入库。
- 失败策略:grunt 任务默认以 exit code 驱动流程,因此用
--failOnUploadFailure --failOnAssertFailure保证红线阻断;若需软阻断,可在 grunt-run 里加failOnError: false,再手动解析lhr-.json中的score < 0.9项,用 grunt.log.warn 输出而不中断构建。 - 国内加速:lhci collect 阶段默认从
https://fonts.googleapis.com拉取字体,CI 机器无外网时需加 chrome-flags--disable-web-security --block-urls=*googleapis.com,否则超时导致得分失真。 - 并行优化:在 Grunt 多 target 场景下,用
grunt-concurrent把 Lighthouse 扫描任务与压缩、上传 CDN 任务并行,平均节省 25% 流水线时间。
答案
-
安装依赖
npm i -D @lhci/cli grunt-run grunt-contrib-connect -
准备待测产物
在 Gruntfile 中先定义build任务,输出到dist/;随后用connect:dist起本地 0.0.0.0:8000 服务,保证 Lighthouse 可访问。 -
编写 LHCI 配置
lighthouserc.jsmodule.exports = { ci: { collect: { startServerCommand: '', // 已在 grunt 里启动 url: ['http://localhost:8000/index.html'], numberOfRuns: 3, settings: { chromeFlags: '--disable-storage-reset --block-urls=*googleapis.com' } }, assert: { preset: 'lighthouse:recommended', assertions: { 'categories:performance': ['error', { minScore: 0.9 }], 'uses-webp': 'off' // 国内 CDN 误报多,先关闭 } }, upload: { target: 'filesystem', outputDir: '.lighthouseci' } } }; -
在 Gruntfile 注册任务
grunt.loadNpmTasks('grunt-run'); grunt.initConfig({ run: { lighthouse: { cmd: 'npx', args: ['lhci', 'autorun'], options: { cwd: __dirname, env: process.env } } }, connect: { dist: { options: { port: 8000, base: 'dist' } } } }); grunt.registerTask('perf', ['build', 'connect:dist', 'run:lighthouse']); -
接入 CI
在.gitlab-ci.yml中声明artifacts:paths: [.lighthouseci],并设置仅当分支为 main 时触发 perf 任务,实现**“开发分支不卡,主干红线卡”**策略。 -
报告消费
用jq解析.lighthouseci/lhr-*.json,把categories.performance.score写入云监控自定义指标,实现版本级性能趋势可视化。
拓展思考
- 如果公司项目为微前端多仓库,可在根仓库用 grunt-hub 统一聚合各子仓库的 Lighthouse 报告,一次流水线产出全局性能雷达图。
- 对于需要登录态的后台系统,Lighthouse 的
--extra-headers方案维护成本高,建议把登录 Cookie 写入localStorage后,用 Puppeteer 脚本先跑一遍登录,再把 Chrome 用户目录传给 LHCI,既保证得分真实,又不泄露账号密码。 - 当构建节点为内网 Jenkins + Windows Slave 时,Chrome 安装路径不固定,可在 Grunt 任务里动态查询注册表获取
chrome.exe绝对路径,再写到CHROME_PATH环境变量,避免“找不到浏览器”导致 CI 随机失败。