Vue 3 与 Lighthouse 性能审计
概述
Lighthouse 是 Google 开发的一款开源性能审计工具,用于评估 Web 应用的性能、可访问性、最佳实践、SEO 和 PWA 等方面。它可以生成详细的审计报告,帮助开发者识别并修复应用中的问题,优化用户体验。与 Vue 3 结合使用,可以全面评估 Vue 3 应用的性能状况,提供具体的优化建议。本集将深入探讨 Lighthouse 的使用方法和最佳实践,帮助你构建高性能的 Vue 3 应用。
核心知识点
1. Lighthouse 基本概念
Lighthouse 提供了多种审计类别,包括:
- **性能 (Performance)**:评估页面加载速度和响应性能
- **可访问性 (Accessibility)**:评估页面对所有用户的可访问性
- **最佳实践 (Best Practices)**:评估页面是否遵循 Web 开发最佳实践
- **SEO (Search Engine Optimization)**:评估页面的搜索引擎优化情况
- **PWA (Progressive Web App)**:评估页面是否符合 PWA 标准
2. 使用 Lighthouse 的方法
Lighthouse 可以通过多种方式使用:
2.1 Chrome DevTools
- 打开 Chrome 浏览器
- 按 F12 打开 DevTools
- 切换到 "Lighthouse" 选项卡
- 选择要审计的类别
- 点击 "Generate report" 生成报告
2.2 命令行工具
# 安装 Lighthouse
npm install -g lighthouse
# 运行审计
lighthouse https://example.com --output html --output-path report.html
# 运行特定类别审计
lighthouse https://example.com --only-categories=performance,accessibility
# 使用 Chrome 扩展程序
lighthouse https://example.com --chrome-flags="--headless"2.3 Node.js API
// src/utils/lighthouse-audit.js
const lighthouse = require('lighthouse')
const chromeLauncher = require('chrome-launcher')
async function runLighthouseAudit(url) {
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] })
const options = {
logLevel: 'info',
output: 'html',
onlyCategories: ['performance', 'accessibility', 'best-practices', 'seo'],
port: chrome.port
}
const runnerResult = await lighthouse(url, options)
await chrome.kill()
return runnerResult
}
// 使用示例
runLighthouseAudit('http://localhost:5173').then(result => {
console.log(`报告生成成功: ${result.report}`)
console.log(`性能分数: ${result.lhr.categories.performance.score * 100}`)
})2.4 GitHub Actions 集成
# .github/workflows/lighthouse.yml
name: Lighthouse Audit
on: [push]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm run build
- run: npm run preview &
- uses: treosh/lighthouse-ci-action@v9
with:
urls: |
http://localhost:4173/
uploadArtifacts: true
temporaryPublicStorage: true3. 性能指标详解
Lighthouse 性能审计基于以下核心 Web 指标:
3.1 First Contentful Paint (FCP)
首次内容ful绘制时间,表示页面上首次出现内容的时间。
优化建议:
- 减少关键资源大小
- 优化服务器响应时间
- 启用资源预加载
3.2 Largest Contentful Paint (LCP)
最大内容ful绘制时间,表示页面上最大内容元素出现的时间。
优化建议:
- 优化图片、视频等大型资源
- 减少 JavaScript 执行时间
- 优化字体加载
3.3 First Input Delay (FID)
首次输入延迟,表示用户首次与页面交互到浏览器响应的时间。
优化建议:
- 减少 JavaScript 执行时间
- 使用 Web Workers 处理耗时任务
- 优化长任务
3.4 Cumulative Layout Shift (CLS)
累积布局偏移,表示页面元素在加载过程中的意外移动程度。
优化建议:
- 为图片和视频设置固定尺寸
- 避免动态插入内容
- 使用 CSS Transform 进行动画
3.5 Time to Interactive (TTI)
可交互时间,表示页面完全可交互的时间。
优化建议:
- 减少关键 JavaScript 大小
- 优化 JavaScript 执行顺序
- 延迟加载非关键资源
4. Vue 3 应用的 Lighthouse 审计
4.1 构建优化
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
build: {
// 启用代码分割
rollupOptions: {
output: {
manualChunks: {
// 将 Vue 相关库打包到一个 chunk
vue: ['vue', 'vue-router', 'pinia'],
// 将第三方库打包到一个 chunk
vendor: ['axios', 'lodash-es']
}
}
},
// 启用 CSS 代码分割
cssCodeSplit: true,
// 启用 sourcemap
sourcemap: false,
// 压缩代码
minify: 'terser',
// 优化静态资源
assetsInlineLimit: 4096
},
// 启用预加载
optimizeDeps: {
include: ['vue', 'vue-router', 'pinia']
}
})4.2 资源优化
<!-- src/App.vue -->
<template>
<div>
<!-- 使用延迟加载图片 -->
<img
v-for="image in images"
:key="image.id"
:src="image.src"
:alt="image.alt"
loading="lazy"
width="300"
height="200"
/>
<!-- 使用响应式图片 -->
<picture>
<source srcset="image.webp" type="image/webp" />
<img src="image.jpg" alt="Image" width="300" height="200" />
</picture>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const images = ref([
{ id: 1, src: 'image1.jpg', alt: 'Image 1' },
{ id: 2, src: 'image2.jpg', alt: 'Image 2' }
])
</script>4.3 字体优化
/* src/assets/styles/fonts.css */
/* 预加载关键字体 */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('/fonts/inter-regular.woff2') format('woff2');
}
/* 使用系统字体栈作为备选 */
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}4.4 路由懒加载
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/HomeView.vue')
},
{
path: '/about',
name: 'about',
// 懒加载路由组件
component: () => import('../views/AboutView.vue')
},
{
path: '/heavy',
name: 'heavy',
// 懒加载重型组件
component: () => import('../views/HeavyView.vue')
}
]
})
export default router4.5 组件懒加载
<!-- src/components/LazyComponent.vue -->
<template>
<div class="lazy-component">
<h2>Lazy Component</h2>
<HeavyContent />
</div>
</template>
<script setup lang="ts">
// 懒加载重型组件
const HeavyContent = () => import('../components/HeavyContent.vue')
</script>4.6 减少 JavaScript 执行时间
<!-- src/components/PerformanceOptimizedComponent.vue -->
<template>
<div class="optimized-component">
<h2>Optimized Component</h2>
<div v-for="item in visibleItems" :key="item.id">
{{ item.name }}
</div>
<button @click="loadMore">Load More</button>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
const allItems = ref([])
const visibleCount = ref(20)
// 只渲染可见的项目
const visibleItems = computed(() => {
return allItems.value.slice(0, visibleCount.value)
})
// 延迟加载更多项目
const loadMore = () => {
visibleCount.value += 20
}
// 模拟数据加载
const loadData = async () => {
// 使用 requestIdleCallback 延迟非关键任务
if ('requestIdleCallback' in window) {
window.requestIdleCallback(async () => {
// 模拟异步数据加载
await new Promise(resolve => setTimeout(resolve, 500))
allItems.value = Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `Item ${i}`
}))
})
} else {
// 不支持 requestIdleCallback 时的回退方案
setTimeout(async () => {
await new Promise(resolve => setTimeout(resolve, 500))
allItems.value = Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `Item ${i}`
}))
}, 0)
}
}
loadData()
</script>5. 分析 Lighthouse 报告
Lighthouse 报告包含以下主要部分:
5.1 摘要
显示各审计类别的得分和总体评价。
5.2 性能指标
显示核心 Web 指标的具体数值和评价。
5.3 机会
提供具体的优化建议,包括:
- 减少未使用的 JavaScript
- 优化图片
- 启用文本压缩
- 减少服务器响应时间
5.4 诊断
提供更详细的性能诊断信息,包括:
- 资源加载时间
- JavaScript 执行时间
- 渲染阻塞资源
5.5 通过率
显示通过的审计项和未通过的审计项。
最佳实践
1. 定期运行 Lighthouse 审计
定期运行 Lighthouse 审计,监控应用性能变化:
# 添加到 package.json
{
"scripts": {
"audit": "lighthouse http://localhost:5173 --output html --output-path lighthouse-report.html"
}
}
# 运行审计
npm run audit2. 关注核心 Web 指标
优先优化核心 Web 指标,这些指标直接影响用户体验:
- Largest Contentful Paint (LCP)
- First Input Delay (FID)
- Cumulative Layout Shift (CLS)
3. 优化构建配置
使用 Vite 的构建优化选项,减少资源大小和加载时间:
// vite.config.ts
export default defineConfig({
build: {
// 启用代码分割
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
vendor: ['axios', 'lodash-es']
}
}
},
// 启用 CSS 代码分割
cssCodeSplit: true,
// 压缩代码
minify: 'terser'
}
})4. 优化资源加载
- 使用延迟加载(lazy loading)处理图片和视频
- 使用响应式图片(responsive images)
- 优化字体加载,使用
font-display: swap - 启用资源预加载(preload)和预连接(preconnect)
5. 减少 JavaScript 执行时间
- 减少关键 JavaScript 大小
- 使用 Web Workers 处理耗时任务
- 优化长任务
- 延迟加载非关键 JavaScript
6. 优化渲染性能
- 避免布局抖动(layout thrashing)
- 使用 CSS Transform 进行动画
- 减少重排(reflow)和重绘(repaint)
- 优化虚拟滚动
7. 确保可访问性
- 使用语义化 HTML
- 为图片添加 alt 文本
- 确保足够的对比度
- 支持键盘导航
8. 遵循 SEO 最佳实践
- 优化页面标题和元描述
- 使用语义化 HTML
- 确保页面可被搜索引擎爬虫访问
- 优化网站结构和导航
常见问题和解决方案
1. 审计分数不稳定
问题:在不同时间运行 Lighthouse 审计,得到不同的分数
解决方案:
- 在相同的网络条件下运行审计
- 使用
--throttling-method=devtools选项 - 多次运行审计,取平均值
2. 本地审计分数与生产环境不同
问题:本地运行 Lighthouse 审计分数高,但生产环境分数低
解决方案:
- 在生产环境运行审计
- 检查生产环境的服务器配置
- 检查 CDN 配置
- 检查生产环境的构建配置
3. 某些资源未被审计
问题:Lighthouse 审计未包含某些资源
解决方案:
- 确保资源在审计过程中被加载
- 检查资源的加载方式
- 使用
--max-wait-for-load=30000选项增加等待时间
4. 无法审计本地开发服务器
问题:无法使用 Lighthouse 审计本地开发服务器
解决方案:
- 确保本地服务器可以被外部访问
- 使用
--chrome-flags="--disable-web-security"选项 - 构建生产版本,使用静态服务器提供服务
5. 审计报告过大
问题:Lighthouse 生成的报告过大
解决方案:
- 使用
--output json选项生成 JSON 格式报告 - 使用
--only-categories选项只审计特定类别 - 使用 Lighthouse CI 进行持续审计
进阶学习资源
官方文档:
工具和库:
性能优化指南:
学习案例:
实践练习
练习 1:基础 Lighthouse 审计
- 初始化一个 Vue 3 项目
- 使用 Chrome DevTools 运行 Lighthouse 审计
- 分析审计报告,识别性能问题
- 修复发现的问题,重新运行审计
练习 2:构建优化
- 配置 Vite 的构建优化选项
- 启用代码分割和懒加载
- 优化图片和字体加载
- 运行 Lighthouse 审计,验证优化效果
练习 3:核心 Web 指标优化
- 识别影响核心 Web 指标的问题
- 优化 Largest Contentful Paint (LCP)
- 优化 Cumulative Layout Shift (CLS)
- 优化 First Input Delay (FID)
- 运行 Lighthouse 审计,验证优化效果
练习 4:自动化审计
- 配置命令行 Lighthouse 审计
- 将审计添加到 package.json 脚本
- 配置 GitHub Actions 自动审计
- 分析自动生成的审计报告
练习 5:综合性能优化
- 实现一个复杂的 Vue 3 应用
- 运行 Lighthouse 审计,识别所有问题
- 按照优先级修复问题
- 持续优化,直到达到良好的审计分数
总结
Lighthouse 是评估和优化 Vue 3 应用性能的强大工具。通过定期运行 Lighthouse 审计,关注核心 Web 指标,优化构建配置和资源加载,你可以构建高性能的 Vue 3 应用,提供优秀的用户体验。Lighthouse 报告提供了具体的优化建议,帮助你识别并修复应用中的问题。结合 Vue 3 的组合式 API 和 Vite 的构建优化,你可以轻松实现高性能的 Vue 3 应用。
下一集我们将学习 Vue 3 与 Sentry 错误监控,敬请期待!