# 性能数据指标理解
最近接触过IntersectionObserver和PerformanceObserver,对其总是理解不深,现在结合代码,对其做一个二次梳理,加深理解。
# IntersectionObserver
# 定义解释
IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
创建一个新的IntersectionObserver对象,当其监听到目标元素的可见部分穿过了一个或多个阈(thresholds)时,会执行指定的回调函数。
IntersectionObserver.observe()使IntersectionObserver开始监听一个目标元素
IntersectionObserver.unobserve()使IntersectionObserver停止监听特定目标元素
v-seen指令添加到lazy-load的图片标签上; v-seen指令inserted的回调函数的内容是:1.当元素处于页面相交(曝光)的区域时记录元素开始曝光时间 ,2.当图片loaded时去计算每个图片的loadedTime,并保留所有图片中加载的最大值;3.页面load后对所有lazyload的图片元素添加observe(为什么是这个时机) 用IntersectionObserver监听body根元素里面的所有图片元素,当他们在可视区域(isIntersecting)的时候就执行回调,执行完回调后,删除observe(即停止监听特定目标元素)
获取出首屏绘制时的所有图片组件,然后统计首屏的图片组件完成图片加载的时间点作为含图片加载页面首屏时长以此计算含图片加载的页面秒开率
目前有一个新的 IntersectionObserver API,可以自动"观察"元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"
# 如何判断元素是否在首屏内?
document.querySelector('body') 如果对body设置了高度100%,那body的高度就是视窗的高度(即首屏的高度),否则就是文档的高度(即包含滚动条的高度) 可以根据这个来判断元素是否在首屏内
# PerformanceObserver
# 定义解释
PerformanceObserver 用于监测性能度量事件,在浏览器的性能时间轴记录下一个新的 performance entries 的时候将会被通知 。
PerformanceObserver.observe()指定监测的 entry types 的集合。 当 performance entry 被记录并且是指定的 entryTypes 之一的时候,性能观察者对象的回调函数会被调用。
资源的性能数据上报 性能插件install时,就添加资源(图片+接口请求)的观察者; 异步等到页面load后对资源(图片+接口请求)添加性能observe(为什么是这个时机) 记录图片和接口加载的时间并完成上报 Performance 页面性能数据上报 使用performace API,拿到fp,fcp时间,同时用首屏图片加载的最大时间(currentTime - navigationStart)作为fmp时间并上报
PerformanceTiming.navigationStart 是一个返回代表一个时刻的 unsigned long long 型只读属性,为紧接着在相同的浏览环境下卸载前一个文档结束之时的 Unix毫秒时间戳。如果没有上一个文档,则它的值相当于 PerformanceTiming.fetchStart。
# 图片懒加载——当图片滚动到可见时才进行加载
图片懒加载和页面的load事件的关系。
load事件 当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。
它与DOMContentLoaded不同,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。
为啥对图片加载的observe需要放在pageload事件之后呢?
# 性能指标详细说明
对各个指标做一个说明,同时附上阿里云上查询数据的sql,便于理解数据。
# 1.首字节时间(t_ttfb)-自行上报(/web-track/performance)
发起页面请求,到浏览器接收到HTML文档的第一个字节
SELECT approx_percentile(t_ttfb, 0.90) as tp90_time from (select * from log where project = 'tutor-lesson' and t_ttfb > 0)
# 2.首次渲染时间(t_fp)-自行上报(/web-track/performance)
它代表网页的第一个像素渲染到屏幕上所用时间,也就是页面在屏幕上首次发生视觉变化的时间;
project: tutor-lesson and event: '/web-track/performance' and t_fp > 0 | SELECT approx_percentile(t_fp, 0.90) as p90_time
# 3.dom ready时间(t_dom)-webTrack统一上报
完成html的加载及解析工作,加载head及body中的js&css静态文件,构建DOM及CSSOM,合并成渲染树
and project:video-template and event:/web-track/performance and t_dom>0 | SELECT approx_percentile(t_dom, 0.90) as p90_time
# 4.页面完全加载时间(t_onload)-webTrack统一上报
页面布局及绘制完成,开始加载异步资源,同时也会下载字体、图片等远程资源,加载完成后触发浏览器的onload事件
project:tutor-lesson and event:/web-track/performance and t_onload>0 | SELECT approx_percentile(t_onload, 0.90) as p90_time
使用的是:performance.timing
2
timing.loadEventEnd - timing.navigationStart
这里可以通过优化图片加载的时间来提升页面完全加载的时间。
# 5.首屏请求p90时间(t_load)-自行上报(duration时间)
首屏请求90分位值的时间
PerformanceObserver中的
a.initiatorType === 'xmlhttprequest' && new RegExp('/leo-midas(.*)/api/').test(a.name)
duration 时间
# 6.FMP时间(t_fmp)-自行上报(/web-track/performance)
异步资源及接口信息返回后对资源进行更新,dom结构达到稳定状态后记录为首屏时间
project: tutor-lesson and event: '/web-track/performance' | SELECT approx_percentile(t_fmp, 0.90) as p90_time
# 7.页面秒开率(t_fmp<1000ms)-自行上报(/web-track/performance)
fmp时间小于1s的占比
SELECT round((direct_count * 100.00 / pv), 2) as direct_rate from (select COUNT(*) as pv, count_if(t_fmp < 1000) as direct_count from log where project = 'tutor-lesson' and event = '/web-track/performance' and t_fmp > 0 )
# 8.图片直出率(t_load<30ms)-自行上报(imgSeenToLoaded)
load完成-开始曝光 的时间<30ms
SELECT round((direct_count *100.0 / pv), 2) as direct_rate from (select COUNT(1) as pv, count_if(t_load < 30) as direct_count from log where project = 'video-template' and event = 'imgSeenToLoaded')
← 如何解决定时器时间不准的问题 图片性能优化 →