首屏时间

概念定义

首屏范围的界定:【top: 0, left: 0, width: 100vw, height: 100vh】

这里的首屏指代,页面首次加载时,当前屏幕内 DOM 内容。针对首屏时间的计算,目前只考虑包含图片和不包含图片的场景

  • 首屏有图片

    首屏时间 = 首屏图片全部加载完毕时刻 - window.performance.timing.navigationStart

  • 首屏无图片

    首屏时间 = 页面处于稳定状态前最后一次 DOM 变动的时刻 - window.performance.timing.navigationStart

    背景图片的加载不会触发 DOM 的变动

实现原理

  • 从页面加载开始,按照一定间隔打点,记录首屏 DOM 变动时刻 T1

  • 记录打点时刻,首屏内图片的加载完成时刻(performance.timing 中获取)T2

  • 找出 DOM 的最后变动时的打点时刻 T1‘,以及此刻首屏内最后一张图片的加载完成时刻 T2’

  • 对比 T1‘ 和 T2’,取较大者作为首屏时间

如何获取首屏内图片的加载完成时刻?

基于 MutationObserver 的监听操作不适用于图片的加载,图片的加载不会触发 MutationObserver 的响应。此时要依赖 PerformanceObserver ,通过监听资源的变动情况,结合判断该资源是否属于首屏,来确定首屏内图片的最后完成时刻。

const observer = new PerformanceObserver(list => {
	// new added resource entries
  const entries = list.getEntries();
});
observer.observer({ entryTypes: ['resource'] });

具体实现

  • 使用 MutationObserver 监听 DOM 改动

    首屏时间_第1张图片

    mutaCallback 中打点记录每次 DOM 变更时刻

  • 对比首屏图片耗时

    首屏时间_第2张图片

首屏内图片统计,需包括背景图在内,允许添加标记来忽略对应元素

首屏时间_第3张图片

使用范围

该方案基于 performance 的 timing API 来统计图片的请求和响应耗时,对于不兼容 performance 的浏览器,首屏图片耗时将不被统计,回归到常规方案

异常因素

  • 首屏外图片

    不管图片还是背景图,只要其不在首屏范围内,则不纳入统计范围

  • base64 图片

    base64 图片的加载等同于加载本地图片,资源耗时不纳入统计范围(归属于所在 JS 或者 CSS 资源耗时)

  • 含忽略标记元素(只影响图片统计)

    图片耗时统计时将被忽略

限制

  • 间隔时间:方案设定 DOM 内容 3000 ms 内不变动,则认为之前最近的一次打点时间为首屏时间

  • performance: 图片加载耗时依赖 performance,不兼容浏览器,将不会纳入统计

  • 性能损耗

    拿到 performance.timing 中的图片资源后,需要剔除非首屏图片。这个过程中,需要遍历当前屏幕中的 DOM 节点,找出 img 和包含背景图的节点。

    判断节点是否包含背景图,需要借助 window.getComputedStyle 函数,来实时计算当前节点的最终样式,该函数的调用会触发 DOM 的重新绘制, 具体参见 what-force-layout

补充说明

首屏时间,大部分会比 DOMContentLoaded,甚至比 window 的 load 还要晚。

这里的首屏,是指有意义内容的首屏。对比出现 Loading 动画,首屏着重于 Loading 动画结束后的内容,对用户真正有用的内容。

如果首屏中包含图片,就要等屏幕中的图片都加载完成。但是,图片的加载并不会触发 MutationObserver,这是计算首屏时间需要解决的一个点。

参考

  • MutationObserver

  • 如何自动获取首屏时间

  • what-force-layout

你可能感兴趣的:(前端-埋点,面试)