性能优化:如何用 Lighthouse 揪出拖慢页面的元凶?
Lighthouse 是什么
Lighthouse 是 Google 开发的开源自动化工具,用于改进网页质量。它可以作为 Chrome 扩展程序运行,也可以通过命令行或 Node 模块使用。Lighthouse 会对网页运行一系列测试,然后生成关于页面性能、可访问性、渐进式 Web 应用等方面的报告。
安装 Lighthouse 最简单的方式是通过 Chrome 扩展:
chrome://extensions/ -> 搜索 "Lighthouse" -> 添加至 Chrome
或者通过 npm 全局安装:
npm install -g lighthouse
性能指标解读
Lighthouse 的性能报告包含多个关键指标,每个指标都反映了页面加载的不同方面:
- 首次内容绘制 (FCP): 测量页面从开始加载到页面内容的任何部分在屏幕上呈现的时间
- 最大内容绘制 (LCP): 测量视口内可见的最大内容元素何时完成渲染
- 速度指数 (SI): 测量页面内容在视觉上显示的速度
- 总阻塞时间 (TBT): 测量主线程被阻塞的时间,导致页面无法响应用户输入
- 累积布局偏移 (CLS): 测量页面加载期间意外布局偏移的频率
例如,一个电商网站的 LCP 可能是产品主图:
<!-- 这是典型的 LCP 元素 -->
<img src="product-image.jpg" alt="产品主图" class="product-image">
运行 Lighthouse 测试
运行 Lighthouse 测试有多种方式:
通过 Chrome DevTools:
- 打开 Chrome 开发者工具 (F12)
- 切换到 Lighthouse 标签页
- 选择需要的类别(性能、PWA 等)
- 点击"生成报告"
通过命令行:
lighthouse https://example.com --view --preset=desktop
通过 Node.js API:
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runLighthouse(url) {
const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
const options = {logLevel: 'info', output: 'html', port: chrome.port};
const runnerResult = await lighthouse(url, options);
// 输出报告
console.log('性能分数:', runnerResult.lhr.categories.performance.score * 100);
await chrome.kill();
return runnerResult.report;
}
分析性能瓶颈
拿到 Lighthouse 报告后,重点关注"Opportunities"和"Diagnostics"部分:
常见性能问题包括:
-
未优化的图片
// 使用 WebP 格式替代 JPEG/PNG <picture> <source srcset="image.webp" type="image/webp"> <img src="image.jpg" alt="示例图片"> </picture>
-
未使用的 JavaScript
// 使用代码分割动态加载非关键 JS import('./module.js').then(module => { module.init(); });
-
过多的 DOM 元素
<!-- 简化复杂 DOM 结构 --> <div class="card"> <h3>产品标题</h3> <p>简短描述</p> </div>
-
未压缩的资源
# 使用 Brotli 压缩 Accept-Encoding: br
优化关键渲染路径
优化关键渲染路径可以显著提升 FCP 和 LCP:
-
内联关键 CSS
<style> /* 关键 CSS 直接内联 */ .header { color: #333; } </style>
-
延迟加载非关键 JS
<script src="non-critical.js" defer></script>
-
预加载关键资源
<link rel="preload" href="font.woff2" as="font" crossorigin>
-
使用服务端渲染 (SSR)
// Next.js 示例 export async function getServerSideProps() { const data = await fetchData(); return { props: { data } }; }
优化 JavaScript 执行
JavaScript 是导致 TBT 高的主要原因:
-
代码拆分
// 动态导入 const module = await import('./heavyModule.js');
-
Web Worker 处理耗时任务
// main.js const worker = new Worker('worker.js'); worker.postMessage(data); // worker.js onmessage = (e) => { const result = processData(e.data); postMessage(result); };
-
避免长任务
// 将长任务分解 function processInChunks() { setTimeout(() => { // 处理一部分数据 if (hasMore) processInChunks(); }, 0); }
-
优化事件处理
// 使用防抖/节流 window.addEventListener('scroll', throttle(handleScroll, 200));
优化 CSS 性能
CSS 处理不当会导致布局抖动和渲染阻塞:
-
避免 @import
/* 不好 */ @import url('other.css'); /* 好 */ <link rel="stylesheet" href="styles.css">
-
使用 will-change
.animate { will-change: transform; }
-
减少重排
// 批量 DOM 操作 const fragment = document.createDocumentFragment(); items.forEach(item => { const el = document.createElement('div'); fragment.appendChild(el); }); container.appendChild(fragment);
-
使用 contain 属性
.isolated-component { contain: layout paint; }
网络优化策略
网络请求是影响加载性能的关键因素:
-
HTTP/2 服务器推送
# nginx 配置 http2_push /style.css; http2_push /app.js;
-
资源提示
<link rel="preconnect" href="https://cdn.example.com"> <link rel="dns-prefetch" href="https://cdn.example.com">
-
智能缓存策略
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 1y; add_header Cache-Control "public, immutable"; }
-
CDN 优化
<!-- 使用多个 CDN 域名并行加载 --> <script src="https://cdn1.example.com/jquery.js"></script> <script src="https://cdn2.example.com/lodash.js"></script>
监控与持续优化
性能优化不是一次性的工作:
-
建立性能预算
// package.json "performanceBudget": { "resources": [ { "resourceType": "script", "budget": 100 } ] }
-
集成到 CI/CD
# GitHub Actions 示例 - name: Run Lighthouse run: | npm install -g lighthouse lighthouse https://your-site.com --output=json --output-path=./lhreport.json
-
真实用户监控 (RUM)
// 使用 Navigation Timing API const [pageNav] = performance.getEntriesByType("navigation"); console.log('LCP:', pageNav.loadEventEnd);
-
A/B 测试优化效果
// 使用 Google Optimize gtag('event', 'optimize.load', { 'experiment_id': 'AbCdEfGhIjKlMnOpQrStUv', 'variant': '0' });
高级优化技巧
对于追求极致性能的场景:
-
边缘计算
// Cloudflare Workers 示例 addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) })
-
自适应加载
if (navigator.connection.effectiveType === '4g') { loadHighResImages(); } else { loadLowResImages(); }
-
WebAssembly 优化
// 加载 WASM 模块 WebAssembly.instantiateStreaming(fetch('module.wasm'), imports) .then(obj => obj.instance.exports.foo());
-
服务器组件
// React Server Components import db from 'db'; async function Note({id}) { const note = await db.posts.get(id); return <NoteView note={note} />; }
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn