PerformanceObserver 性能条目类型(Entry Types)

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:资源 URL
  • entry.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,可以构建全面的前端性能监控体系,为优化提供数据支撑

相关推荐
xw514 分钟前
npm几个实用命令
前端·npm
!win !18 分钟前
npm几个实用命令
前端·npm
代码狂想家23 分钟前
使用openEuler从零构建用户管理系统Web应用平台
前端
dorisrv2 小时前
优雅的React表单状态管理
前端
蓝瑟2 小时前
告别重复造轮子!业务组件多场景复用实战指南
前端·javascript·设计模式
dorisrv2 小时前
高性能的懒加载与无限滚动实现
前端
韭菜炒大葱3 小时前
别等了!用 Vue 3 让 AI 边想边说,字字蹦到你脸上
前端·vue.js·aigc
StarkCoder3 小时前
求求你,别在 Swift 协程开头写 guard let self = self 了!
前端
清妍_3 小时前
一文详解 Taro / 小程序 IntersectionObserver 参数
前端
电商API大数据接口开发Cris3 小时前
构建异步任务队列:高效批量化获取淘宝关键词搜索结果的实践
前端·数据挖掘·api