1.首屏时间概念
即页面首屏可以完全渲染出来,并且用户可以完全交互。一般首屏时间小于页面完全加载时间。通常项目中通过首屏时间来衡量页面的访问速度。
对于首屏的定义,浏览器没有给出标准的指标,因为不同网站对于首屏的要求也是不尽相同的。我们从谷歌的第一次有效时间(first meaningfull paint)得到了一些启发,例如,一个新闻网站文字跟字体对于它来说是更重要的,而图片是次要的。新闻网站可以认为所有文字或字体加载出来即为首屏。但是对于电商网站来说,电商网站的图片可能更加重要,因为图片占据整个网站的80%以上。所以仅仅字体或文字被加载出来并不能定义为首屏时间。以此可以看出,首屏并不是一个可以通过简单的api就能计算出来的,首屏的方案也是因公司而异的。幸运的是,浏览器提供了各种监测性能及dom的api,可以让我们通过这些api来计算首屏时间。
但是有一个共同的认知是:首屏时间是指dom比较稳定的一个阶段
performance API 通过window.permformance.timing可以获取当前页面期间发生的各种事件的性能计时信息,以下为各个事件的展示图
-
DNS 查询耗时:
domainLookupEnd - domainLookupStart
-
TCP 连接耗时:
connectEnd - connectStart
-
内容加载耗时:
responseEnd - requestStart
-
firstbyte(首包时间):
responseStart – domainLookupStart
-
fpt(First Paint Time 首次渲染时间 / 白屏时间):
responseEnd – fetchStart
-
tti(Time to Interact 首次可交互时间):
domInteractive – fetchStart
-
ready(HTML 加载完成时间):
domContentLoaded – fetchStart
-
load(页面完全加载时间):
loadEventStart – fetchStart
目前白屏常见的优化方案有:
- SSR
- 预渲染
- 骨架屏
优化首屏加载时间的方法:
- CDN分发(减少传输距离)
- 后端在业务层的缓存
- 静态文件缓存方案
- 前端的资源动态加载
- 减少请求的数量
- 利用好HTTP压缩
2.目前业界计算首屏时间的方式
-
用户自定义打点—最准确的方式(只有用户自己最清楚,什么样的时间才算是首屏加载完成)
- 缺点:侵入业务,成本高
-
粗略的计算首屏时间:
loadEventEnd - fetchStart/startTime
或者domInteractive - fetchStart/startTime
-
通过计算首屏区域内的所有图片加载时间,然后取其最大值
-
利用 MutationObserver 接口,监听 document 对象的节点变化
2.1 服务端渲染的首屏时间:首屏时间的标志是ssr使用的dom渲染结束
2.2 spa渲染的首屏时间:FMP首次meaningful内容绘制时间
3.采用performance API计算首屏时间的问题
performance计算白屏时间(FP)是比较准确的,但是对于首屏时间(FCP,content painting)是不准确的,因为首屏时间的计算公式可以表示为:
首屏时间 = 首屏内容渲染结束时间点 - 发出请求的时间点。
这里的发出请求时间点的指标是明确的,但是首屏内容渲染结束的时间点中怎么定义首屏是问题?并且这个首屏渲染结束的时间点如何获取也是一个问题(因为目前没有一个API可以获取),比如长夜页面的首屏时间不会统计视口下面的渲染,或者首屏内容值得是有效内容,对于部分图片加载不完全也是可以忽略的。所以首屏渲染时间统计方式业界是没有统一计算标准的。
按照performance API去计算首屏时间的话,一般是按照两个事件点计算,一种是domcontentload事件发生的时间作为首屏时间,另一种是按照load时间作为首屏时间,但是这两个事件计算中,都存在缺点。
domContentLoad事件和load事件的区别
1.domContentLoad事件
这个事件是指html文件加载和完全解析的时候,会触发这个“dom内容加载完成”事件。需要注意的是,这个事件的触发时机是:初始的html文档被完全加载和完全解析之后就会触发。和样式表、图片和子框架是否加载完全没有直接关系。
以此事件作为首屏标志的缺点是,spa中渲染的内容是通过js加载的,而domcontentload并不会等待main.js加载完成,所以这中方式计算时间明显是漏掉了,算少了。
2.load事件:
是指这个html文件中所依赖的资源都加载完成才会触发,即html中srcipt标签中的资源加载完全,img标签图片加载完全或者link标签的css资源加载完全等这一系列依赖都加载完全后,才会触发load事件。
总结:这两个事件的区别在于,一个只关心html是够完全解析完, 另一个不单单是html解析还包括依赖资源的加载。
以此事件作为首屏标志的缺点是,视口之外的时间也被计算在内,或者对于有效内容作为首屏的话,这个时间又变得太长了,所以也不是很准确,那么首屏时间就是First Meaningful Paint(FMP)
总结:performance API计算白屏时间还算准确,但是计算首屏时间会有问题 blog.csdn.net/qq_32682137…
4.采用 MutationObserver 计算首屏时间
参考文献:juejin.cn/post/703564… juejin.cn/post/684490… juejin.cn/post/695093…