前言
前段时间在研究前端异常监控平台,在思考性能监控时,想到了浏览器自带的观察者以及页面生命周期API 。于是在翻查资料时发现了,Performance Observer
API。正好趁着这个机会给大家好好讲讲Performance Observer API
Performance Observer(性能观察者)
定义
Performance Observer
是一种JavaScript API,用于监测页面性能指标,如资源加载时间、页面渲染时间等。它可以触发回调函数,以便你收集和分析页面性能数据。
优点
- 性能监测:可以监测页面性能,以便发现性能问题并进行优化。
- 丰富的性能指标:提供了多种性能指标,如资源加载时间、首次绘制时间等,帮助开发人员深入了解页面性能。
- 跨浏览器支持:Performance Observer是一个标准的Web API,被主流浏览器支持。
应用场景
- 性能优化:可以使用Performance Observer来监测页面性能,以发现潜在的性能瓶颈并进行优化。
- 用户体验分析:可以收集性能数据,以分析用户在页面加载和交互过程中的体验。
- 性能报告:可以生成性能报告,以帮助开发团队了解页面性能的历史数据。
用法
1.创建Performance Observer实例
首先,我们需要创建一个Performance Observer的实例。它需要一个回调函数作为参数,这个回调函数会在性能指标发生变化时被触发。
const observer = new PerformanceObserver(callback);
2.指定要观察的性能条目类型
然后,我们需要指定要观察的性能条目类型。性能条目类型是一个配置对象,包括以下属性:
-
entryTypes
:一个数组,包含要观察的性能条目类型。可以填的值包括: frame: 指的是整个页面,包括页面的导航性能和整体加载时间。它可以监测与整个页面的性能相关的数据。 navigation: 与页面导航和加载时间相关,提供有关导航事件(如页面加载、重定向等)的性能数据。 resource: 与页面中加载的各种资源相关,如图像、脚本、样式表等。它可以监测单个资源的加载性能,包括资源的开始和结束时间,以及其他相关信息。 mark: 与性能标记(mark)相关,性能标记是在代码中设置的时间戳,通常用于记录特定事件的时间,以便后续性能分析。这提供了在页面加载期间创建性能标记的方式。 measure: 与性能测量(measure)相关,性能测量用于测量两个性能标记之间的时间间隔,以获取更详细的性能数据。这提供了测量和分析特定事件之间的时间差的方式。 paint: 与页面绘制性能相关,可以是 "first-paint"(首次绘制)或 "first-contentful-paint"(首次内容绘制)之一。这些指标表示页面呈现的关键时间点,可以帮助我们评估用户视觉上的加载体验。
代码示例:
observer.observe({ entryTypes: ['resource', 'paint'] });
3.编写回调函数
回调函数会在性能指标发生变化时被触发,它接受一个参数:entries
,它是一个性能条目对象的数组,每个对象描述了一个性能条目。
const callback = entries => {entries.forEach(entry => {// 处理性能指标数据});
};
4.Performance的方法
observe方法
observe
方法用于启动性能观察器以开始监测指定类型的性能条目。options
方法接受一个参数,参数要求是对象形式,其中包含要监测的性能条目类型(entryTypes
)和一个回调函数,用于处理观察到的性能条目。当指定的性能条目可用时,会触发回调函数。
参数包含的值:
-
entryTypes
(必需): 一个字符串数组,用于指定要监测的性能条目类型。 -
buffered
(可选):一个布尔值,指示是否应该检查已缓冲的性能条目(默认为false
)。如果设置为true
,则性能观察器将检查在调用observe
之前已经发生的性能条目。 -
transferMode
(可选) 一个字符串,用于指定如何传输性能条目。可以包括以下值:- “report”:默认值,性能条目将通过回调函数进行报告。
- “accumulate”:性能条目将积累并传递给回调函数。
代码示例:
observer.observe({entryTypes: ['navigation', 'resource'],buffered: true, // 检查已缓冲的性能条目 transferMode: 'report', // 默认值,性能条目通过回调函数进行报告
});
disconnect()
方法
用于停止性能观察器的观察,即停止监测性能条目。一旦调用
disconnect
方法,性能观察器将不再触发回调函数。
代码示例:
observer.disconnect(); // 调用 disconnect 方法停止性能观察
takeRecords()
方法
用于获取当前性能观察器队列中尚未传递给回调函数的性能条目。这些性能条目会从队列中移除,并以数组的形式返回。这可以在停止观察之前用于检索观察到的性能数据。
代码示例:
// 创建一个 PerformanceObserver 对象
const observer = new PerformanceObserver((list) => {const entries = list.getEntries();for (const entry of entries) {// 处理性能数据的代码console.log(entry);}
});// 配置性能观察器以监测导航性能
observer.observe({ entryTypes: ['navigation'] });// 某些时间后,手动获取尚未传递的性能条目
setTimeout(() => {const unprocessedEntries = observer.takeRecords();for (const entry of unprocessedEntries) {// 处理尚未传递的性能数据的代码console.log('Unprocessed entry:', entry);}
}, 5000); // 在5秒后手动获取尚未传递的性能条目
代码实战
我们可以创建一个PerformanceObserver 对象,来监听 mark(时间点)、measure(时间段)、resource(资源加载耗时) 这三种记录时间的行为。
然后我们用 mark 记录了某个时间点,点击 button 的时候用 measure 记录了某个时间段的数据,还加载了一个图片。
当这些记录行为发生的时候我么把性能数据打印在控制台或者上报给我们的监控系统。
jcode
mark(时间点)数据
name
(名称):性能标记的名称,这里是 “translate:initiated”。它表示一个特定时间点的标记,通常用于记录页面加载过程中的关键时间点或事件。entryType
(条目类型):指示性能条目的类型,对于PerformanceMark
来说,它是 “mark”,表明这是一个性能标记的条目。startTime
(开始时间):性能标记的时间戳,以浏览器的导航开始时间为基准,通常以毫秒(ms)为单位。在这个例子中,标记的时间是从导航开始时开始计算的,为 342.6 毫秒。duration
(持续时间):对于PerformanceMark
来说,它始终是 0,因为标记只表示一个瞬时的时间点,没有持续时间。
measure(时间段)数据
"name": "button clicked"
:这是性能测量的名称。它表示测量的类型或描述,这里是 “button clicked”,表明这个测量是与按钮点击事件相关的。"entryType": "measure"
:这表示这个性能条目的类型是 “measure”。"startTime": 0
:这是测量的开始时间,"duration": 4088.7999999523163
:这是性能测量的持续时间,表示从测量开始到测量结束的时间差,同样以毫秒(ms)为单位。在这里,测量的持续时间为 4088.8 毫秒,表示按钮点击事件的执行时间。
(图片)资源加载性能
name
(名称):资源的名称或 URL。entryType
(条目类型):指示性能条目的类型,对于PerformanceResourceTiming
来说,它是 “resource”,表明这是一个与资源加载性能相关的条目。startTime
(开始时间):资源加载开始的时间,以浏览器的导航开始时间为基准,通常以毫秒(ms)为单位。在我们这个例子中,资源加载开始于 301.4 毫秒。duration
(持续时间):资源加载的持续时间,以毫秒(ms)为单位。这个资源加载持续时间为 0,表示加载是瞬时完成的。initiatorType
(发起者类型):指示加载资源的方式或来源类型。这里是 “img”,表示该资源是通过img
元素加载的。nextHopProtocol
(下一跳协议):资源加载时使用的网络协议,这里为空白,表示未指定。renderBlockingStatus
(阻塞状态):指示资源加载是否会阻塞渲染。这里是 “non-blocking”,表示该资源加载不会阻塞页面的渲染。workerStart
:相关于资源加载的事件,这里是 0,表示资源加载事件尚未开始。redirectStart
和redirectEnd
:相关于重定向的事件,这里都是 0,表示没有发生重定向。fetchStart
:资源请求开始的时间,与导航开始时间的时间差,这里是 301.4 毫秒。domainLookupStart
和domainLookupEnd
:与域名解析(DNS 查询)相关的事件,这里都是 0,表示域名解析尚未发生。connectStart
和connectEnd
:与建立连接相关的事件,这里都是 0,表示尚未建立连接。- 其他属性,如
secureConnectionStart
、requestStart
、responseStart
等,用于记录资源加载过程中的不同事件时间。 transferSize
、encodedBodySize
、decodedBodySize
:与资源大小和传输相关的属性。在这个例子中,它们都为 0,表示资源大小很小,没有传输。responseStatus
:资源加载的响应状态码,这里是 0,表示没有响应状态码。serverTiming
:服务器定时信息,通常用于记录服务器端性能信息。
总结
有了Performance Observer API,后,我们可以更精确地监测和分析网页的性能表现,它可以帮助我们发现和解决潜在的性能问题。但是我们在使用的时候还是需要小心地选择要监测的内容,避免引入额外的性能开销,特别是在处理大量数据时。