如何实现首屏时间采集的自动化解决方案?

摘要:关于首屏 首屏时间是指从转向该页面到屏幕中该页面所有内容都可见时的时间。已经有太多的关于首屏时间的计算,在本文中并不重复阐述这些已经被提出或者实现的方案,而旨在探索与讨论更多的首屏自动化采集方案,扩大思考范围,你我思想之间
关于首屏 首屏时间是指从转向该页面到屏幕中该页面所有内容都可见时的时间。已经有太多的关于首屏时间的计算,在本文中并不重复阐述这些已经被提出或者实现的方案,而旨在探索与讨论更多的首屏自动化采集方案,扩大思考范围,你我思想之间互相碰撞往往可以激起更多的稀奇古怪的解决方案,这也正是我写这篇文章的目的。 通过浏览器调试工具,我们可以清晰的看出页面资源加载时序图: 先是html页面加载,token进行词法、语法解析后开始加载静态资源并执行相关脚本,开始构建DOM树、render树和CSSOM数,最后加载图片,用户看到完整的网页。 虽然浏览器有着各自的优化的解决方案,但是大多数情况下图片往往是最后加载完毕,这不仅仅是由于图片的大小相对较大,而且图片的加载与否与DOM结构有着很大的关系。DOM是否构建完毕,render树中是否渲染以及其他的图片加载策略有关系可能都会影响图片加载时序。因此在首屏时间的计算中,我们是以最终首屏图片的加载时间为节点计算的。 首屏计算 原则1 首屏计算模块不应该耦合业务线 一般而言,首屏计算作为一个抽离出的js脚本单独引用,这个模块尽量不暴露API给开发者使用,所有的采集端任务都由该模块完成。这句话可能听起来像一句废话,但还是有很多情况可能需要业务人员来进行首屏渲染时间的判断的,下面将针对这个情形举一个实际的场景: 随着MVVM模式的兴起,前端异步渲染逐渐流行起来,前端编码逐渐由面向jQuery编程转向为面向Vue编程。可是使用Vue编写的业务代码在本地打包后仅仅是一个bundle,此时的HTML文件中只是一个 的占位符而已,那么首屏时间计算模块该如何准确的计算首屏时间呢?因此首屏时间计算模块必须知道首屏的DOM结构渲染完毕的时间节点,在这个节点时刻进行计算首屏范围内的图片加载时间。 可是如何获取首屏DOM结构渲染完毕的时间节点呢?这就需要业务开发人员制定。在更新vue实例的data属性后,通知首屏计算模块此时DOM接口已渲染完毕,开始计算首屏时间。 MVVM开发模式下,首屏时间的计算已经耦合了业务代码,虽然可以在保证首屏时间的准确性,但却给开发者带来了一些可观判断逻辑,而这些判断往往会困扰新入职的同志们,因此我们的目标之一就是解决需要手动打点进行首屏时间计算的现状。 原则2 性能与准确性的权衡 业界有个通过canvas截屏并通过轮询对比不同时间点截屏图片之间某几个随机像素点,从而判断首屏是否加载完毕。这种方式虽然科学,但是估计没有几个公司会采用这种方案。通过canvas截屏这个操作对硬件的要求可能就比较高,而且需要进行额外的像素运算,因此性能肯定很差。其实这种场景在工程领域经常出现,工程不同于科学那般严谨,我们只需要找到给定条件的最优解即可,做工程也就是在做trade off。因此这种对比方案我们也必须摒弃。 实现 再次强调,由开发者打点首屏DOM渲染完毕进行首屏时间计算的方式是相对准确的方式,因此我们后续讨论的自动化计算首屏时间的准确性都是基于此标准进行对比说明,因为自动化计算肯定是没有人工干预准确的,这一点毫无疑问。 轮训采集大法 仍然是轮训,不同的是在每次轮询中执行一些操作: 获取首屏的所有图片(包括IMG标签与css相关属性) 绑定首屏图片的onload和onerror事件,每次轮询不会重复绑定已绑定的图片 相同图片不需重复绑定事件侦听,否则会与 2 中的每次轮询混淆 图片的事件处理函数执行打点信息并统计图片加载状态,同时比对时间戳得到最迟加载的时间 具体的实现中,需要特别注意首屏出现的相同图片的情况。笔者起初在获取首屏图片中简单计算图片的url数组,存储重复图片的个数,并且与该图片的加载状态绑定在一起。如首屏中出现了3张相同的图片,那么在该图片onload或onerror中对已加载图片的数量做 加3 处理,否则导致最终的 已加载图片总数 与 首屏图片总数 不相等的情况发生。这种实现导致逻辑非常的差,且实现复杂。后通过存储图片所在的DOM对象数组实现更为简单的图片状态判断,更加已读。
阅读全文