PerformanceObserver 是 Web 性能监测的核心 API,通过指定 entryTypes 可以观察不同类型的性能指标。以下是所有支持的条目类型及其详细说明。
一、核心 Entry Types 列表
1. 'navigation' --- 页面导航性能
说明:测量主文档的导航和加载时间,提供完整的页面加载生命周期数据。
常用指标:
entry.duration:总加载时间entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart:DOM 解析时间entry.loadEventEnd - entry.loadEventStart:资源加载时间
使用场景:分析页面整体加载性能,计算 DNS、TCP、TTFB 等关键指标
2. 'resource' --- 资源加载性能
说明:测量页面上所有资源的加载时间,包括图片、CSS、JavaScript、XHR/Fetch 请求等。
关键属性:
entry.name:资源 URLentry.initiatorType:资源类型(img,script,link,xmlhttprequest,fetch)entry.duration:加载耗时entry.decodedBodySize:资源大小
使用场景:定位慢资源、监控 CDN 效果、优化资源加载策略
3. 'paint' --- 渲染性能
说明 :测量关键渲染时间点,主要用于 FCP(首次内容绘制)。
事件名称:
entry.name === 'first-contentful-paint':FCP 时间
使用场景:Core Web Vitals 核心指标监控
4. 'largest-contentful-paint' --- 最大内容绘制
说明 :作为独立条目类型提供更精确的 LCP 数据,包含详细的元素信息。
关键属性:
entry.startTime:LCP 发生时间entry.element:触发 LCP 的 DOM 元素entry.url:图片资源的 URL(如适用)
使用场景:精准定位影响 LCP 的元素,优化最大内容加载
php
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(' LCP 详情:', {
time: entry.startTime.toFixed(2) + 'ms',
element: entry.element?.tagName,
url: entry.url
});
}
});
observer.observe({ entryTypes: ['largest-contentful-paint'], buffered: true });
5. 'first-input' --- 首次输入延迟
说明 :测量用户首次交互(点击、触摸、按键)到浏览器响应的延迟时间,是 Core Web Vitals 核心指标。
关键属性:
entry.name:交互类型(click,pointerdown,keydown)entry.duration:总延迟时间entry.processingStart/entry.processingEnd:事件处理时间
使用场景:评估用户对应用响应性的第一印象
php
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('首次交互延迟:', {
type: entry.name,
delay: entry.duration + 'ms'
});
}
});
observer.observe({ entryTypes: ['first-input'], buffered: true });
6. 'layout-shift' --- 布局偏移(CLS)
说明 :测量页面元素的意外移动,用于计算 Cumulative Layout Shift (CLS) 。
关键属性:
entry.value:单次布局偏移得分entry.hadRecentInput:是否由用户输入触发(通常只关注false的情况)
使用场景:提升视觉稳定性,优化用户体验
7. 'event' --- 用户事件延迟
说明:测量所有用户交互事件(点击、键盘输入)的延迟时间。
关键属性:
entry.name:事件类型(click,keydown等)entry.duration:事件处理耗时
使用场景:监控交互响应性,发现事件处理瓶颈
8. 'longtask' --- 长任务监控
说明 :识别主线程上耗时超过 50 毫秒的任务,这些任务会阻塞用户交互。
关键属性:
entry.duration:任务耗时entry.attribution:导致长任务的代码信息
使用场景:发现 JavaScript 性能瓶颈,优化主线程执行
9. 'long-animation-frame' --- 长动画帧(LoAF)
说明 :新一代长任务监控 ,比 'longtask' 更细粒度,提供完整的调用栈和脚本归因。
关键属性:
entry.duration:帧耗时entry.scripts:详细的脚本执行信息数组
使用场景:精确诊断阻塞动画和交互的脚本
php
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('长动画帧:', {
duration: entry.duration + 'ms',
scripts: entry.scripts.map(s => ({
source: s.sourceURL,
function: s.sourceFunctionName,
duration: s.duration + 'ms'
}))
});
}
});
observer.observe({ entryTypes: ['long-animation-frame'], buffered: true });
10. 'element' --- 元素级性能
说明:观察特定 DOM 元素的渲染时间,用于更精确的 LCP 测量。
使用要求 :元素需添加 elementtiming 属性
ini
<img src="hero.jpg" elementtiming="hero-image" />
使用场景:监控关键业务元素的渲染性能
11. 'mark' --- 自定义时间戳标记
说明 :通过 performance.mark() 创建命名时间戳,标记业务关键节点。
使用方式:
arduino
performance.mark('user_login_start');
// ... 执行代码
performance.mark('user_login_end');
使用场景:自定义业务逻辑性能监控,如组件初始化时间、API 调用耗时等
javascript
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntriesByType('mark')) {
console.log('标记点:', entry.name, entry.startTime + 'ms');
}
});
observer.observe({ entryTypes: ['mark'], buffered: true });
12. 'measure' --- 自定义时间区间测量
说明 :通过 performance.measure() 计算两个 mark 之间的时间差,是业务性能监控的黄金标准。
使用方式:
arduino
performance.measure('login_duration', 'user_login_start', 'user_login_end');
使用场景:精确测量业务操作耗时,生成自定义性能指标
javascript
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntriesByType('measure')) {
console.log('测量区间:', entry.name, entry.duration + 'ms');
}
});
observer.observe({ entryTypes: ['measure'], buffered: true });
13. 'visibility-state' --- 页面可见性变化
说明 :监控页面从可见到隐藏、从隐藏到可见的状态转换,对移动端性能优化至关重要。
关键属性:
entry.prevState:之前的状态(visible,hidden,prerender)entry.currState:当前的状态
使用场景:页面隐藏时暂停非关键任务,节省 CPU 和电量
php
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('可见性变化:', {
from: entry.prevState,
to: entry.currState
});
if (entry.currState === 'hidden') {
pauseBackgroundTasks();
}
}
});
observer.observe({ entryTypes: ['visibility-state'], buffered: true });
二、浏览器兼容性说明
动态检查支持类型
通过 PerformanceObserver.supportedEntryTypes 获取当前浏览器支持的类型:
perl
console.log(PerformanceObserver.supportedEntryTypes);
// 现代浏览器输出 (13):
// ['element', 'event', 'first-input', 'largest-contentful-paint',
// 'layout-shift', 'long-animation-frame', 'longtask', 'mark',
// 'measure', 'navigation', 'paint', 'resource', 'visibility-state']
注意 :该属性是静态只读属性,返回数组reactnative.dev/docs/next/g...
兼容性差异
- 现代浏览器 (Chrome 120+, Edge 120+):支持全部 13 种类型
- Safari :支持基础类型,对新类型(如
long-animation-frame)支持较慢 - Firefox:支持核心类型,部分实验性类型不支持
- IE:完全不支持 PerformanceObserver
推荐做法:
ini
const supportedTypes = PerformanceObserver.supportedEntryTypes || [];
const desiredTypes = [
'navigation', 'resource', 'paint', 'first-input', 'layout-shift',
'longtask', 'event', 'largest-contentful-paint', 'long-animation-frame'
];
const entryTypes = desiredTypes.filter(type => supportedTypes.includes(type));
if (entryTypes.length > 0) {
observer.observe({ entryTypes, buffered: true });
}
三、完整使用示例
监控多种性能指标
javascript
// 创建观察者实例
const observer = new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
entries.forEach(entry => {
console.log(`类型: ${entry.entryType}, 名称: ${entry.name}, 耗时: ${entry.duration}ms`);
// 根据类型分别处理
switch(entry.entryType) {
case 'navigation':
console.log('页面加载完成:', entry.duration + 'ms');
break;
case 'resource':
if (entry.duration > 200) {
console.warn('慢资源:', entry.name);
}
break;
case 'largest-contentful-paint':
console.log('LCP:', entry.startTime.toFixed(2) + 'ms');
break;
case 'first-input':
console.log('🖱️ 首次交互延迟:', entry.duration + 'ms');
break;
case 'layout-shift':
if (!entry.hadRecentInput) {
console.log('CLS 累积:', entry.value);
}
break;
case 'long-animation-frame':
console.error('长动画帧:', entry.duration + 'ms');
break;
case 'visibility-state':
console.log('可见性变化:', entry.currState);
break;
}
});
});
// 开始观察(推荐设置 buffered: true 获取历史数据)
observer.observe({
entryTypes: [
'navigation',
'resource',
'largest-contentful-paint',
'first-input',
'layout-shift',
'long-animation-frame',
'visibility-state'
],
buffered: true
});
关键点:
buffered: true:收集observe()调用之前已发生的性能条目,防止遗漏disconnect():不再需要时调用,释放资源
五、总结矩阵
| # | Entry Type | 主要指标 | 典型阈值 | 所属标准 | 监控场景 |
|---|---|---|---|---|---|
| 1 | navigation |
页面加载时间 | < 3s | Navigation Timing | 整体加载性能 |
| 2 | resource |
资源加载耗时 | < 200ms | Resource Timing | 慢资源定位 |
| 3 | paint |
FCP | < 1.8s | Paint Timing | 首次渲染 |
| 4 | largest-contentful-paint |
LCP | < 2.5s | LCP API | 最大内容渲染 |
| 5 | first-input |
FID | < 100ms | Event Timing | 首次交互响应 |
| 6 | layout-shift |
CLS | < 0.1 | Layout Instability | 视觉稳定性 |
| 7 | event |
交互延迟 | < 100ms | Event Timing | 所有事件延迟 |
| 8 | longtask |
主线程阻塞 | > 50ms | Long Tasks API | 卡顿检测 |
| 9 | long-animation-frame |
长动画帧阻塞 | > 50ms | LoAF API | 精细化卡顿分析 |
| 10 | element |
元素渲染时间 | 业务自定义 | Element Timing | 关键元素监控 |
| 11 | mark |
自定义时间戳 | - | User Timing | 业务埋点 |
| 12 | measure |
自定义时间区间 | 业务自定义 | User Timing | 区间测量 |
| 13 | visibility-state |
页面可见性变化 | - | Page Visibility | 节能优化 |
通过合理组合这些 entry types,可以构建全面的前端性能监控体系,为优化提供数据支撑