AI智能摘要
GPT
本文讨论如何在CI/CD流程中实现自动化提交和PR级别性能测试,重点利用GitHub Actions和Lighthouse CI工具。文章解析Lighthouse的评估指标及其在网页性能优化中的重要性,指导如何集成Lighthouse测试以生成自动报告,并提出设置性能阈值和定期监测的最佳实践,以确保网站性能的持续改进。
本文介绍了如何利用 CI/CD 流水线实现自动提交和 PR 级别的性能测试,以及如何通过 GitHub Actions 和 Lighthouse CI 工具实现这一目标。文章详细解释了 Lighthouse 的各项评估指标及其在网页性能优化中的作用,以及如何在 CI/CD 流水线中集成 Lighthouse 测试并自动化生成报告。此外,还探讨了如何通过设置阈值检测和定期监测来确保网站性能的持续优化。
自用全专线,小贵但效果超好 Aifun 爱翻 - 机场测评
引言
网站性能对用户体验和 SEO 影响深远,而 Lighthouse 是前端性能测试的利器。但手动测试既费时又容易遗漏,如何在 CI/CD 流水线中自动化进行提交和 PR 级别的性能测试?GitHub Action 提供一种CI/CD 流水线中自动化的可能,让每一次代码提交和 PR 都能触发 Lighthouse 监测,确保性能始终在线!
什么是 Lighthouse?
Lighthouse 作为一款开源的自动化测试工具,能够帮助开发者全面分析网页质量,并提供优化建议。无论是公开网页还是需要身份验证的页面,Lighthouse 都能进行深入审核,确保网站在各个方面达到最佳状态。
Lighthouse 主要从以下几个方面对网页进行评估:
✅ 性能 (Performance): 分析页面加载速度,优化资源请求,减少渲染阻塞,提高交互体验。
✅ 可访问性 (Accessibility): 确保网站对所有用户(包括有视觉或听觉障碍的人)都能友好访问。
✅ 渐进式 Web 应用 (PWA): 评估网站是否符合 PWA 标准,例如离线访问能力和响应式设计。
✅ 最佳实践 (Best Practices): 检查网站是否符合现代 Web 开发规范,例如 HTTPS 安全性、资源加载优化等。
✅ SEO (搜索引擎优化): 评估网页是否满足搜索引擎的最佳索引标准,提高页面排名。
什么是 Lighthouse CI?
Lighthouse CI 是一套工具,旨在让 Lighthouse 测试的自动执行、结果存储、数据检索和结果校验变得更加简单高效。它能够帮助开发者在 CI/CD 流水线中持续运行 Lighthouse 测试,并轻松管理测试结果,让网站性能优化变得更加智能化和可追踪。
如何在 CI/CD 中使用?
我们可以利用 GitHub Actions 配置一个自动化流程,每次代码提交或 PR 触发时,运行 Lighthouse 测试并生成报告。
配置 GitHub Actions
给出的示例是基于在Vercel进行部署的,不过其他方式是同理的
核心就是要等待新的部署(CD)完成,Actions能够检测到完成,然后触发 Lighthouse审计即可
检测新的部署(CD)完成的方式:(笔者已知)
- 云平台:
- 在Actions中通过云平台API进行部署,执行完成则为部署完成
- 在Actions中不断轮询检测是否完成,检测到则为部署完成
- PR时工作流
在项目的
.github/workflows
目录下创建一个新的工作流文件,例如 pr-lighthouse.yml
,内容如下:具体代码
name: pr-deploy-and-audit on: [pull_request] jobs: deploy_and_audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Vercel Action id: vercel_action uses: amondnet/vercel-action@v25.2.0 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID}} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID}} scope: ${{ secrets.VERCEL_SCOPE }} - name: Add comment to PR id: loading_lighthouse_comment_to_pr uses: marocchino/sticky-pull-request-comment@v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ github.event.pull_request.number }} header: lighthouse message: | 🚦 Running Lighthouse audit... - name: Add comment to PR id: loading_budget_comment_to_pr uses: marocchino/sticky-pull-request-comment@v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ github.event.pull_request.number }} header: budget message: | ⏱ Running budget checks... - name: Audit URLs using Lighthouse id: lighthouse_audit uses: treosh/lighthouse-ci-action@v12 with: # add as many urls here as you wish to audit # prefixed by the preview-url urls: | ${{ steps.vercel_action.outputs.preview-url }} runs: 3 # 取决于具体 lighthouse配置 configPath: './lighthouserc.js' serverBaseUrl: ${{ secrets.LHCI_SERVER_URL }} serverToken: ${{ secrets.LHCI_SERVER_TOKEN }} basicAuthUsername: ${{ secrets.LHCI_BASIC_AUTH_USERNAME }} basicAuthPassword: ${{ secrets.LHCI_BASIC_AUTH_PASSWORD }} - name: Format lighthouse result id: lighthouse_result if: ${{ always() }} uses: actions/github-script@v7 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | const links = ${{ steps.lighthouse_audit.outputs.links }} const results = (${{ steps.lighthouse_audit.outputs.assertionResults }}).filter(result => result.isRepresentativeRun); const score = res => res >= 90 ? '🟢' : res >= 50 ? '🟠' : '🔴'; const comment = results.map((result) => { const summary = result.summary; const url = result.url; return ` 🌎 [${url}](${url}) ⚡️ [Lighthouse report](${links[url]}) | Category | Score | | --- | --- | ${Object.keys(summary).map((key) => { const percentage = Math.round(summary[key] * 100); return `| ${score(percentage)} ${key} | ${percentage} |`; }).join('\n')} `; }).join('---'); core.setOutput("comment", comment); - name: Format budget result id: budget_result if: ${{ always() }} uses: actions/github-script@v7 with: github-token: ${{secrets.GITHUB_TOKEN}} script: | const assertions = ${{ steps.lighthouse_audit.outputs.assertionResults }}; if (!assertions.length) { core.setOutput("comment", '✅ Budget met, nothing to see here'); } else { const comment = assertions.map((result) => { return ` ❌ **${result.auditProperty || ''}.${result.auditId}** failure on [${result.url}](${result.url}) *${result.auditTitle}* - [docs](${result.auditDocumentationLink}) | Actual | Expected | | --- | --- | | ${result.actual} | ${result.operator} ${result.expected} | `; }).join('---'); core.setOutput("comment", comment); } - name: Add Lighthouse comment to PR id: lighthouse_comment_to_pr if: ${{ always() }} uses: marocchino/sticky-pull-request-comment@v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ github.event.pull_request.number }} header: lighthouse message: | ${{ steps.lighthouse_result.outputs.result }} - name: Add Budget comment to PR id: budget_comment_to_pr if: ${{ always() }} uses: marocchino/sticky-pull-request-comment@v2 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} number: ${{ github.event.pull_request.number }} header: budget message: | ${{ steps.budget_result.outputs.result }}
- Commit代码提交时工作流
在项目的
.github/workflows
目录下创建一个新的工作流文件,例如 commit-lighthouse.yml
,内容如下:具体代码
name: CI on: [push] jobs: lhci: name: Lighthouse runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Vercel Action id: vercel_action uses: amondnet/vercel-action@v25.2.0 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID}} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID}} scope: ${{ secrets.VERCEL_SCOPE }} - name: Audit Vercel preview URL using Lighthouse uses: treosh/lighthouse-ci-action@v12 with: urls: | ${{ steps.urls.outputs.urls }} runs: 3 # 取决于具体 lighthouse配置 configPath: './lighthouserc.js' serverBaseUrl: ${{ secrets.LHCI_SERVER_URL }} serverToken: ${{ secrets.LHCI_SERVER_TOKEN }} basicAuthUsername: ${{ secrets.LHCI_BASIC_AUTH_USERNAME }} basicAuthPassword: ${{ secrets.LHCI_BASIC_AUTH_PASSWORD }}
所需环境变量配置
- vercel-action 请见
- lighthouse 部分请见
进阶设置
- 对特定分支进行持续跟踪(Vercel专属)
- 存在的问题
- 解决方案
因为 Vercel-Action 默认部署和返回的是 Vercel的随机URL格式(每次部署不同),而非分支URL格式,导致测试URL每次不一致,在使用Lighthouse服务器时,无法有效比较每次数据
在每次部署的时候也会比常规生成的缺少分支URL格式,不只是影响后续操作
对于vercel-action增加 alias-domains 配置,手动生成一个与Vercel自动生成一致格式的 git branch 分支,后续outputs的URL也会是这个
- name: Vercel Action id: vercel_action uses: amondnet/vercel-action@v25.2.0 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID}} # 增加 alias-domains 配置,手动生成一个与Vercel自动生成一致格式的 git branch 分支 alias-domains: ${{ secrets.PROJECT_NAME}}-git-{{ BRANCH }}-${{ secrets.TEAM_NAME}}.vercel.app vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID}} scope: ${{ secrets.VERCEL_SCOPE }}
- 使用自己的 Lighthouse Server
可以历史记录和更多统计数据和数据对比
Lighthouse 部署教程
施工中🚧
进阶优化建议
设置性能阈值
可以在 CI 中加入Lighthouse 阈值检测,当性能下降超过一定范围时,让 CI 任务失败,强制开发者优化代码。
定期进行 Lighthouse 测试
除了 PR 触发测试,也可以定期执行 Lighthouse 监测,防止长期累积的性能问题。
结合 Web Vitals 监控
可以搭配 Web Vitals 监控工具,实时分析用户访问的真实性能数据。
暂无
自用全专线,小贵但效果超好 Aifun 爱翻 - 机场测评
📎 参考文章
主要参考 暂无
还可以加入Telegram的七行的小仓库|互联网记忆|博客 和七行 技术交流群 找到更多小技巧哦🥰,还可以在聊天群探讨各种问题❓
欢迎在底部评论区分享您的想法和经验,让我们一起共同探讨,共同进步!
- 作者:Qi Xing
- 链接:https://blog.qixing1217.top/article/automated-commit-and-pr-performance-testing-with-ci-vercel
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。