Vue 应用的性能预算:CI/CD 集成与性能回归检测
大家好,今天我们来聊聊 Vue 应用的性能预算以及如何在 CI/CD 流程中集成性能回归检测。 性能预算是网站或应用程序在性能方面设定的限制,例如页面加载时间、资源大小等。 严格执行性能预算可以确保用户获得快速、流畅的体验,从而提高用户满意度和转化率。 在持续集成/持续交付 (CI/CD) 管道中集成性能回归检测,能够在代码变更引入性能问题时及时发现并修复,防止性能瓶颈蔓延到生产环境。
一、 为什么需要性能预算?
在深入讨论具体实施之前,我们先来明确性能预算的重要性。 性能对用户体验至关重要。 研究表明,页面加载速度每慢 1 秒,转化率就会下降 7%。 一个响应缓慢的网站会带来以下问题:
- 用户体验下降: 用户会感到沮丧,进而放弃使用。
- 搜索引擎排名降低: 搜索引擎会优先展示速度快的网站。
- 转化率降低: 访问者更有可能离开未完成交易。
- 服务器成本增加: 响应缓慢意味着服务器需要更多资源来处理请求。
通过设定性能预算,我们可以主动地监控和优化应用,确保其始终满足性能要求。
二、 性能预算的构成要素
性能预算通常包含以下几个关键指标:
-
页面加载时间: 指用户从发起请求到页面完全可交互的时间。 常见的指标包括:
- First Contentful Paint (FCP): 浏览器首次渲染任何内容的时间。
- Largest Contentful Paint (LCP): 浏览器首次渲染最大内容元素的时间。
- Time to Interactive (TTI): 页面变得完全可交互的时间。
- Speed Index: 页面内容可视填充的速度。
-
资源大小: 指页面加载所需的所有资源(HTML、CSS、JavaScript、图片、字体等)的总大小。
- 总资源大小: 所有资源的大小总和。
- 单个资源大小: 例如,JavaScript 文件的大小不应超过某个限制。
-
请求数量: 指页面加载期间发出的 HTTP 请求数量。 过多的请求会增加延迟。
-
阻塞渲染的资源: 指阻止浏览器首次渲染页面的资源。 这些资源应该尽可能异步加载或延迟加载。
-
第三方脚本: 指来自第三方服务的 JavaScript 代码。 这些脚本可能会影响性能,因此需要仔细监控。
三、 如何制定性能预算?
制定性能预算需要考虑以下因素:
- 目标用户: 了解你的目标用户所使用的设备、网络环境等。 例如,如果你的用户主要来自移动设备,那么你的性能预算应该更加严格。
- 竞争对手: 分析竞争对手的网站性能,并设定一个比他们更好的目标。
- 业务目标: 性能优化应该服务于业务目标。 例如,如果你的目标是提高转化率,那么你可能需要更加关注页面加载速度。
- 现有性能数据: 使用 Google PageSpeed Insights、WebPageTest 等工具分析现有网站的性能,找出瓶颈。
一个简单的性能预算示例:
| 指标 | 预算值 |
|---|---|
| 页面加载时间(LCP) | < 2.5s |
| 总资源大小 | < 2MB |
| JavaScript 大小 | < 500KB |
| 请求数量 | < 50 |
四、 Vue 应用性能优化的常用策略
在设定性能预算后,我们需要采取措施来优化 Vue 应用的性能。 以下是一些常用的策略:
-
代码拆分 (Code Splitting): 将应用拆分成更小的 chunks,按需加载。 Vue CLI 提供了开箱即用的代码拆分支持。
// 路由懒加载 const Home = () => import(/* webpackChunkName: "home" */ './components/Home.vue') const About = () => import(/* webpackChunkName: "about" */ './components/About.vue') const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] -
路由懒加载 (Lazy Loading): 延迟加载非必要的路由组件。
// Vue Router 配置 const routes = [ { path: '/admin', component: () => import('./components/Admin.vue') // 懒加载 Admin 组件 } ] -
组件懒加载 (Lazy Loading): 延迟加载非必要的组件。
<template> <div> <component :is="currentComponent" /> </div> </template> <script> import { defineAsyncComponent } from 'vue' export default { data() { return { currentComponent: null } }, mounted() { this.currentComponent = defineAsyncComponent(() => import('./components/HeavyComponent.vue')) } } </script> -
图片优化: 压缩图片大小,使用 WebP 格式,使用懒加载。
<img src="placeholder.png" data-src="image.webp" alt="Image" loading="lazy"> -
Gzip/Brotli 压缩: 压缩传输的资源,减少带宽消耗。 通常在服务器端配置。
-
缓存: 使用浏览器缓存和 CDN 缓存静态资源。
-
Tree Shaking: 移除未使用的代码。 Webpack 会自动进行 Tree Shaking。
-
优化组件渲染: 避免不必要的重新渲染,使用
shouldComponentUpdate或Vue.memo。 -
减少第三方依赖: 避免引入不必要的第三方库。
五、 CI/CD 集成:使用 Lighthouse 进行性能回归检测
接下来,我们将讨论如何在 CI/CD 流程中集成性能回归检测。 我们将使用 Google Lighthouse 作为性能分析工具。 Lighthouse 是一个开源的自动化工具,用于改进网页的质量。 它可以对性能、可访问性、渐进式 Web 应用等方面进行审计。
1. 选择 CI/CD 工具
市面上有很多 CI/CD 工具可供选择,例如 Jenkins, GitLab CI, GitHub Actions, CircleCI 等。 这里我们以 GitHub Actions 为例,因为它与 GitHub 集成紧密,使用方便。
2. 创建 Lighthouse 配置文件
我们需要创建一个 Lighthouse 配置文件,指定要审计的 URL、预算指标等。 我们可以使用 Lighthouse 的 CLI 工具生成配置文件:
npm install -g lighthouse
lighthouse --save-assets --save-config https://example.com
这会生成一个 lighthouse-config.js 文件,其中包含默认的配置。 我们可以根据需要修改该文件,例如设置性能预算:
module.exports = {
extends: 'lighthouse:default',
settings: {
onlyCategories: ['performance'],
},
audits: [
'first-contentful-paint',
'largest-contentful-paint',
'speed-index',
'total-blocking-time',
'cumulative-layout-shift',
],
бюджети: [
{
resourceSizes: [
{
resourceType: 'total',
budget: 2000 // 2MB
},
{
resourceType: 'script',
budget: 500 // 500KB
}
]
},
{
timings: [
{
metric: 'first-contentful-paint',
budget: 2500 // 2.5s
},
{
metric: 'largest-contentful-paint',
budget: 2500 // 2.5s
}
]
}
]
};
3. 创建 GitHub Actions Workflow
在你的 GitHub 仓库中创建一个 .github/workflows/performance.yml 文件,并添加以下内容:
name: Performance Audit
on:
push:
branches: [main] # 只在推送到 main 分支时触发
pull_request:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: npm install
- name: Build Application
run: npm run build
- name: Serve Application (using serve)
run: |
npm install -g serve
serve -s dist &
npx wait-on http://localhost:3000
- name: Run Lighthouse Audit
uses: treosh/lighthouse-ci-action@v10
with:
urls: http://localhost:3000
configPath: ./lighthouse-config.js
uploadArtifacts: true # 将 Lighthouse 报告上传为 artifact
temporaryPublicStorage: true # 使用临时公共存储
- name: Lighthouse Report
if: always()
run: |
echo "Lighthouse report is available as an artifact."
echo "See the details in the Checks tab."
这个 workflow 会在每次推送到 main 分支或创建 pull request 时触发。 它会执行以下步骤:
- 检出代码。
- 安装依赖。
- 构建应用。
- 使用
serve启动一个静态服务器, serving 构建后的dist目录。 - 使用
treosh/lighthouse-ci-action运行 Lighthouse 审计,并上传报告为 artifact。
4. 分析 Lighthouse 报告
在 GitHub Actions 运行完成后,你可以在 "Actions" 标签中查看 Lighthouse 报告。 如果任何性能指标超过了预算,Lighthouse 会抛出错误,导致 workflow 失败。 你可以通过查看报告来了解具体的性能问题,并进行修复。
六、 持续监控与告警
CI/CD 集成可以帮助我们及时发现性能回归,但它只能在代码变更时进行检测。 为了确保应用的性能始终符合要求,我们需要进行持续监控和告警。
-
WebPageTest: 可以使用 WebPageTest API 定期测试生产环境的性能,并将结果存储在数据库中。 可以设置告警规则,当性能指标超过阈值时发送通知。
-
Google PageSpeed Insights API: 类似于 WebPageTest,也可以用于定期测试性能并设置告警。
-
Real User Monitoring (RUM): RUM 收集真实用户的性能数据,可以帮助我们了解用户体验。 常见的 RUM 工具包括 New Relic, Datadog, Sentry 等。
七、 代码示例:自定义 Lighthouse Action
虽然 treosh/lighthouse-ci-action 已经很好用,但有时我们需要更细粒度的控制。 下面是一个自定义 Lighthouse Action 的示例,可以更灵活地处理 Lighthouse 报告:
name: Performance Audit
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: npm install
- name: Build Application
run: npm run build
- name: Serve Application (using serve)
run: |
npm install -g serve
serve -s dist &
npx wait-on http://localhost:3000
- name: Run Lighthouse Audit
id: lighthouse
run: |
npm install -g lighthouse
lighthouse --output json --output html --config-path ./lighthouse-config.js http://localhost:3000
mv lighthouse.report.json lighthouse_report.json
mv lighthouse.report.html lighthouse_report.html
echo "lighthouse_report=$(cat lighthouse_report.json)" >> $GITHUB_OUTPUT
- name: Check Performance Budget
run: |
REPORT=$(echo '${{ steps.lighthouse.outputs.lighthouse_report }}' | jq -r .)
FCP=$(echo $REPORT | jq -r '.audits."first-contentful-paint".numericValue')
LCP=$(echo $REPORT | jq -r '.audits."largest-contentful-paint".numericValue')
echo "First Contentful Paint: $FCP"
echo "Largest Contentful Paint: $LCP"
if (( $(echo "$FCP > 2500" | bc -l) )); then
echo "First Contentful Paint exceeds budget (2.5s)"
exit 1
fi
if (( $(echo "$LCP > 2500" | bc -l) )); then
echo "Largest Contentful Paint exceeds budget (2.5s)"
exit 1
fi
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: lighthouse-report
path: ./lighthouse_report.html
这个 workflow 使用 lighthouse 命令直接运行 Lighthouse,并将报告保存为 JSON 和 HTML 文件。 然后,它使用 jq 命令解析 JSON 报告,提取 FCP 和 LCP 指标,并检查它们是否超过了预算。 如果任何指标超过了预算,workflow 将失败。 最后,它将 HTML 报告上传为 artifact。
八、性能优化是一个持续的过程
性能优化不是一次性的任务,而是一个持续的过程。 我们需要定期监控应用的性能,并根据需要进行优化。 CI/CD 集成和性能回归检测可以帮助我们自动化这个过程,确保应用的性能始终符合要求。
九、总结几句
为Vue应用设置性能预算,并在 CI/CD 流程中集成性能回归检测,能帮助我们尽早发现和解决性能问题。持续的性能监控和优化,才能确保用户始终拥有卓越的体验。
更多IT精英技术系列讲座,到智猿学院