通过 Performance 监控性能
约 548 字大约 2 分钟
2024-08-14
Performance API 概述
浏览器提供 Performance API 用于测量页面和应用的性能。
主要接口
Performance:获取页面性能数据PerformanceEntry:性能条目的基类PerformanceMark:自定义标记PerformanceMeasure:自定义测量PerformanceObserver:观察性能指标变化
核心指标
1. 页面加载指标
const perfData = performance.getEntriesByType('navigation')[0];
console.log({
dns: perfData.domainLookupEnd - perfData.domainLookupStart, // DNS 解析
tcp: perfData.connectEnd - perfData.connectStart, // TCP 连接
ssl: perfData.secureConnectionStart > 0
? perfData.connectEnd - perfData.secureConnectionStart : 0, // SSL
ttfb: perfData.responseStart - perfData.requestStart, // 首字节时间
download: perfData.responseEnd - perfData.responseStart, // 下载时间
firstPaint: perfData.loadEventStart - perfData.fetchStart, // 首屏时间
});2. 资源加载时间
const resources = performance.getEntriesByType('resource');
resources.forEach(resource => {
console.log({
name: resource.name,
duration: resource.duration,
size: resource.transferSize,
type: resource.initiatorType
});
});3. Long Tasks API
检测超过 50ms 的长任务:
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log('Long Task:', {
duration: entry.duration,
startTime: entry.startTime,
attribution: entry.attribution
});
});
});
observer.observe({ type: 'longtask', buffered: true });自定义性能标记
// 开始标记
performance.mark('app-start');
// 执行操作
await doSomething();
// 结束标记
performance.mark('app-end');
// 测量两个标记之间的时间
performance.measure('operation-duration', 'app-start', 'app-end');
// 获取测量结果
const measures = performance.getEntriesByType('measure');
console.log(measures);
// 清除标记
performance.clearMarks();
performance.clearMeasures();PerformanceObserver
观察特定类型的性能指标:
// 观察 Paint Timing
const paintObserver = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.name === 'first-contentful-paint') {
console.log('FCP:', entry.startTime);
}
});
});
paintObserver.observe({ type: 'paint', buffered: true });
// 观察长任务
const longTaskObserver = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.warn('Long Task detected:', entry.duration);
});
});
longTaskObserver.observe({ type: 'longtask', buffered: true });
// 观察资源
const resourceObserver = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log('Resource loaded:', entry.name, entry.duration);
});
});
resourceObserver.observe({ type: 'resource', buffered: true });Web Vitals
Google 的核心网页指标:
import { getCLS, getFID, getLCP, getFCP, getTTFB } from 'web-vitals';
getCLS(console.log); // Cumulative Layout Shift
getFID(console.log); // First Input Delay
getLCP(console.log); // Largest Contentful Paint
getFCP(console.log); // First Contentful Paint
getTTFB(console.log); // Time to First Byte内存监控
// 注意:需要 Chrome DevTools 且开启 "记录堆分配"功能
if (performance.memory) {
console.log({
usedJSHeapSize: performance.memory.usedJSHeapSize,
totalJSHeapSize: performance.memory.totalJSHeapSize,
jsHeapSizeLimit: performance.memory.jsHeapSizeLimit
});
}实践建议
- 自动化采集:在生产环境中使用 Performance API 采集真实用户数据
- 采样采集:避免对所有用户进行全量采集
- 结合 RUM:上报到数据分析平台,持续监控性能趋势
- 设置阈值:关键指标超过阈值时触发告警
参考文章:
