Deprecated: 自 6.9.0 版本起,使用参数调用函数 WP_Dependencies->add_data() 已弃用!IE conditional comments are ignored by all supported browsers. in D:\wwwroot\zyxy\wordpress\wp-includes\functions.php on line 6131

Deprecated: 自 6.9.0 版本起,使用参数调用函数 WP_Dependencies->add_data() 已弃用!IE conditional comments are ignored by all supported browsers. in D:\wwwroot\zyxy\wordpress\wp-includes\functions.php on line 6131

Vue应用的性能预算(Performance Budget)配置:CI/CD集成与性能回归检测

Vue 应用的性能预算:CI/CD 集成与性能回归检测

大家好!今天我们来聊聊 Vue 应用的性能预算,以及如何将它集成到 CI/CD 流程中,进行性能回归检测。性能预算是保证用户体验的关键,尤其是在单页应用(SPA)越来越复杂的今天。

什么是性能预算?

性能预算本质上是为你的 Web 应用设定的一系列性能指标的上限。这些指标涵盖了多个方面,例如:

  • 加载时间: 首屏加载时间(First Contentful Paint, FCP)、首次有效绘制(First Meaningful Paint, FMP)、可交互时间(Time to Interactive, TTI)。
  • 资源大小: JavaScript 包大小、CSS 文件大小、图片大小、字体文件大小。
  • HTTP 请求数量: 减少请求数量可以降低延迟。
  • 第三方脚本数量和大小: 第三方脚本可能会影响性能,需要严格控制。
  • 内存占用: 避免内存泄漏和过度占用。
  • CPU 占用: 减少长任务,避免阻塞主线程。

制定性能预算的目的在于:

  1. 设定目标: 明确性能优化的方向。
  2. 预防退化: 在开发过程中及时发现性能问题。
  3. 持续改进: 长期保持良好的性能水平。

制定 Vue 应用的性能预算

制定性能预算需要考虑以下因素:

  • 目标用户: 他们的网络状况、设备性能如何?
  • 应用类型: 电商网站、社交应用还是企业应用?不同类型的应用对性能的要求不同。
  • 竞争对手: 对标竞争对手的性能水平。
  • 业务需求: 哪些功能对性能要求最高?

一个简单的性能预算示例:

指标 预算值 备注
首屏加载时间(FCP) 1.5 秒 用户首次看到内容的时间,对用户体验至关重要。
可交互时间(TTI) 3 秒 应用完全可交互的时间,避免用户长时间等待。
JavaScript 包大小(gzip) 150 KB 过大的 JavaScript 包会导致加载缓慢。
图片总大小 500 KB 优化图片格式和压缩率,减少图片体积。
HTTP 请求数量 20 个 合理合并和优化资源,减少请求数量。
第三方脚本数量 3 个 谨慎引入第三方脚本,并定期审查其性能影响。

关键点: 性能预算并不是一成不变的,需要根据实际情况进行调整。

Vue CLI 中的性能优化配置

Vue CLI 提供了一些内置工具来帮助我们优化性能。

  1. 代码分割 (Code Splitting): 将应用拆分成多个小的 chunk,按需加载,减少首次加载时间。

    vue.config.js 中配置:

    module.exports = {
      configureWebpack: {
        optimization: {
          splitChunks: {
            chunks: 'all',
            cacheGroups: {
              vendors: {
                test: /[\/]node_modules[\/]/,
                priority: -10,
                name: 'vendors'
              },
              common: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true,
                name: 'common'
              }
            }
          }
        }
      }
    }
  2. 懒加载 (Lazy Loading): 延迟加载非必要的组件,提高初始加载速度。

    使用 import() 语法实现懒加载:

    const MyComponent = () => import('./MyComponent.vue');
    
    export default {
      components: {
        MyComponent
      }
    }
  3. 预加载/预取 (Preload/Prefetch): 提前加载关键资源,优化后续导航体验。

    vue.config.js 中配置:

    module.exports = {
      chainWebpack: config => {
        config.plugin('preload').tap(args => {
          args[0].rel = 'preload';
          args[0].include = 'initial';
          return args;
        });
    
        config.plugin('prefetch').tap(args => {
          args[0].rel = 'prefetch';
          args[0].include = 'asyncChunks';
          return args;
        });
      }
    }
  4. Gzip 压缩: 压缩静态资源,减少传输体积。

    Vue CLI 默认开启 Gzip 压缩,可以通过 vue.config.js 进行配置:

    const CompressionWebpackPlugin = require('compression-webpack-plugin');
    
    module.exports = {
      configureWebpack: {
        plugins: [
          new CompressionWebpackPlugin({
            filename: '[path][base].gz',
            algorithm: 'gzip',
            test: /.(js|css|html|svg)$/,
            threshold: 10240,
            minRatio: 0.8,
            deleteOriginalAssets: false
          })
        ]
      }
    }
  5. 图片优化: 使用合适的图片格式(WebP),压缩图片大小。

    可以使用 image-webpack-loader 等工具进行图片优化。

    module.exports = {
      chainWebpack: config => {
        config.module
          .rule('images')
          .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            })
            .end()
      }
    }

CI/CD 集成:性能回归检测

将性能预算集成到 CI/CD 流程中,可以自动化地进行性能回归检测,及时发现并修复性能问题。

常用的工具:

  • Lighthouse: Google 提供的自动化工具,可以分析网页性能并提供优化建议。
  • WebPageTest: 提供详细的性能指标和瀑布图。
  • Sitespeed.io: 开源的网站性能监控工具。
  • Bundle Analyzer: 分析 JavaScript 包大小,找出优化空间。
  • PageSpeed Insights: Google 提供的在线工具,分析网页性能并提供优化建议。

以下以 Lighthouse 为例,说明如何集成到 CI/CD 流程中。

1. 安装 Lighthouse CI:

npm install -g @lhci/cli

2. 配置 Lighthouse CI:

在项目根目录下创建 .lighthouserc.js 文件,配置 Lighthouse CI:

module.exports = {
  ci: {
    collect: {
      url: ['http://localhost:8080'], // 应用的 URL
      numberOfRuns: 3, // 运行 Lighthouse 的次数,取平均值
    },
    assert: {
      preset: 'lighthouse:recommended',
      assertions: {
        'first-contentful-paint': ['warn', { maxNumericValue: 1500 }], // 首屏加载时间限制
        'interactive': ['warn', { maxNumericValue: 3000 }], // 可交互时间限制
        'performance': ['warn', { minScore: 0.9 }], // 性能评分限制
        'largest-contentful-paint': ['warn', { maxNumericValue: 2500 }],
        'total-blocking-time': ['warn', { maxNumericValue: 300 }],
      },
    },
    upload: {
      target: 'temporary-public-storage',
    },
  },
};

3. 在 CI/CD 流程中运行 Lighthouse CI:

例如,使用 GitHub Actions:

name: Lighthouse CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js 16
        uses: actions/setup-node@v2
        with:
          node-version: 16
      - name: Install dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Serve
        run: npm run serve &  # 使用你自己的 serve 命令
        env:
          PORT: 8080
      - name: Run Lighthouse CI
        run: |
          npm install -g @lhci/cli
          lhci autorun

解释:

  • collect.url: 指定要分析的 URL,这里使用 http://localhost:8080。你需要确保应用在 CI 环境中可以访问。
  • collect.numberOfRuns: 运行 Lighthouse 的次数,可以提高结果的准确性。
  • assert.preset: 使用 Lighthouse 推荐的规则。
  • assert.assertions: 自定义性能预算,例如限制首屏加载时间、可交互时间、性能评分等。
  • upload.target: 将 Lighthouse 报告上传到临时公共存储,方便查看。
  • GitHub Actions workflow:
    • actions/checkout@v2: 检出代码。
    • actions/setup-node@v2: 安装 Node.js。
    • npm install: 安装依赖。
    • npm run build: 构建应用。
    • npm run serve: 启动一个本地服务器,用于提供构建后的应用。
    • lhci autorun: 运行 Lighthouse CI。

4. 查看 Lighthouse 报告:

Lighthouse CI 会在 CI/CD 流程中生成报告,你可以通过链接查看详细的性能指标和优化建议。 如果性能指标超出预算,CI/CD 流程会失败,提醒你修复性能问题。

关键点:

  • 根据你的 CI/CD 工具选择合适的集成方式。
  • 根据你的应用特点调整 Lighthouse CI 的配置。
  • 定期审查和更新性能预算。
  • 除了 Lighthouse,还可以结合其他性能监控工具,例如 WebPageTest、Sitespeed.io 等。

Bundle Analyzer 的使用

Bundle Analyzer 可以帮助你分析 JavaScript 包的大小,找出优化空间。

  1. 安装 webpack-bundle-analyzer:

    npm install --save-dev webpack-bundle-analyzer
  2. 配置 vue.config.js:

    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    
    module.exports = {
      configureWebpack: {
        plugins: [
          new BundleAnalyzerPlugin()
        ]
      }
    }
  3. 运行 npm run build:

    构建完成后,Bundle Analyzer 会自动打开一个网页,显示 JavaScript 包的组成和大小。

    通过 Bundle Analyzer,你可以发现:

    • 哪些依赖占用了大量的空间。
    • 是否存在重复的依赖。
    • 是否存在可以移除的依赖。

    然后,你可以根据分析结果进行优化,例如:

    • 使用更小的替代方案。
    • 移除不必要的依赖。
    • 使用代码分割,将大的 chunk 拆分成小的 chunk。

性能优化的 Vue 代码示例

  1. 使用 v-once 指令优化静态内容:

    如果组件的内容是静态的,不会发生变化,可以使用 v-once 指令来避免重复渲染。

    <template>
      <div v-once>
        <h1>This is a static title</h1>
      </div>
    </template>
  2. 使用 v-memo 指令避免不必要的更新: (Vue 3.2+)

    v-memo 指令可以缓存组件的渲染结果,只有当依赖发生变化时才重新渲染。

    <template>
      <div v-memo="[item.id, item.name]">
        {{ item.name }}
      </div>
    </template>
  3. 使用 keep-alive 组件缓存组件:

    keep-alive 组件可以缓存组件的状态,避免组件被销毁和重新创建。

    <template>
      <keep-alive>
        <component :is="currentComponent"></component>
      </keep-alive>
    </template>
  4. 避免在模板中执行复杂的计算:

    将复杂的计算逻辑放在计算属性或方法中,避免在模板中重复计算。

    <template>
      <div>
        {{ formattedDate }}
      </div>
    </template>
    
    <script>
    export default {
      computed: {
        formattedDate() {
          // 将日期格式化逻辑放在计算属性中
          return new Date().toLocaleDateString();
        }
      }
    }
    </script>
  5. 使用事件委托:

    将事件监听器添加到父元素上,利用事件冒泡机制来处理子元素的事件,减少事件监听器的数量。

    <template>
      <ul @click="handleClick">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
      </ul>
    </template>
    
    <script>
    export default {
      methods: {
        handleClick(event) {
          if (event.target.tagName === 'LI') {
            console.log('Clicked on:', event.target.textContent);
          }
        }
      }
    }
    </script>

常见性能问题及解决方案

问题 解决方案
JavaScript 包过大 代码分割、懒加载、移除不必要的依赖、使用更小的替代方案、优化第三方库的使用。
图片过大或格式不合适 使用 WebP 格式、压缩图片大小、使用 CDN、使用懒加载。
HTTP 请求数量过多 合并 CSS 和 JavaScript 文件、使用 CSS Sprites、使用 CDN、利用浏览器缓存。
长任务阻塞主线程 使用 Web Workers 将耗时任务放在后台线程执行、使用 requestAnimationFrame 优化动画。
频繁的 DOM 操作 使用 Vue 的虚拟 DOM 机制、批量更新 DOM、避免在循环中操作 DOM。
内存泄漏 避免创建全局变量、及时释放不再使用的对象、避免循环引用。
第三方脚本性能问题 谨慎引入第三方脚本、定期审查第三方脚本的性能影响、使用异步加载。
过度渲染 (组件不必要地重新渲染) 使用 v-memo (Vue 3.2+)、 v-oncecomputedkeep-alive 组件,合理使用 key 属性,使用 shouldComponentUpdate (在 Options API 中) 或 memo (在 Composition API 中) 来控制组件的更新。

持续监控与优化

性能优化是一个持续的过程,需要不断地监控和优化。

  • 定期运行 Lighthouse CI 或其他性能监控工具。
  • 分析性能报告,找出瓶颈。
  • 根据分析结果进行优化。
  • 重复以上步骤,持续改进。

性能预算保障用户体验,CI/CD 集成自动化检测

性能预算是保障 Vue 应用用户体验的关键,需要根据实际情况制定和调整。将性能预算集成到 CI/CD 流程中,可以自动化地进行性能回归检测,及时发现并修复性能问题。结合各种性能分析工具,持续监控和优化,可以长期保持良好的性能水平。

更多IT精英技术系列讲座,到智猿学院

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注