我们知道要做页面的性能优化就必须得有数据支撑,否则无法衡量页面的性能,优化更是无从谈起。
页面的性能怎么衡量?天下武功唯快不破。快不快是就代表我们页面性能好不好,而时间是快不快的数据指标。
针对时间,W3C工作组提出了一套浏览器加载网页过程中各个时间点的规范,浏览器厂商已经实现了其中一些规范。下面我们就来看看,都有哪些指标,怎么看出网页性能。
PerformanceNavigationTiming
PerformanceEntry接口
所有Performance接口系列都继承了PerformanceEntry接口。
所以先看看这个接口都定义了哪些属性
name
当前网页地址
entryType
在PerformanceNavigationTiming接口中,entryType是'navigation'
startTime
0
duration
loadEventEnd时间点和startTime的时间间隔。
这个值代表了从网页开始加载,到DOM解析完、文档中所有资源下载完的时间。
PerformanceNavigationTiming接口
unloadEventStart
onunload回调执行前的时间点
unloadEventEnd
onunload回调执行完的时间点
domInteractive
document.readystate
变成interactive的时间点
此时DOM已经被解析完,但是其他资源可能正在加载,比如图片、CSS等。
domContentLoadedEventStart
DOM解析完成,开始执行'DOMContentLoaded'回调的时间点
domContentLoadedEventEnd
DOM解析完成,’DOMContentLoaded'回调也执行完的时间点
domComplete
document.readystate
变为'complete'
DOM解析完,文档中的资源文件也全都加载完。
loadEventStart
unload
事件回调开始执行的时间点
这个时候document.readystate
已经是'complete'了
loadEventEnd
unload事件回调执行完的时间点
type
-
navigate
正常导航时的类型,比如浏览器输网址敲回车、a标签跳转、表单提交等等。
总之只要不是下面这几种类型的,都算navigate。
-
reload
刷新网页
-
back_forward
回退进入网页
-
prerender
预渲染网页
SPA页面操作history.pushState
会改变type么?当然不会。因为navigation指的是浏览器加载一个地址的过程。history.back
的话会么?还是这个原则,除非发生页面加载,否则只操作一下历史栈是不会触发navigation的
意义
我们阅读上述接口文档后能够看出来,PerformanceNavigationTiming聚焦在了这段时间:
开始:浏览器开始加载文档(确切说是从上个页面的unload事件开始)
结束:DOM解析完且所有资源加载完。
那这这个接口提供给了我们什么性能分析的指标?那就是DOM解析时间。
阻塞
关于<script>
标签的建议,上古时期有“雅虎军规”,现代浏览器有异步加载。这是为了解决什么问题?
渲染进程的主线程身兼多职,DOM、CSSOM的解析,样式计算,页面布局计算,JavaScript代码都跑在这个线程上,也就是说这些任务在执行时是互斥的。
在解析HTML文档的时候,如果遇到script标签(同步的),不管是内嵌还是外联的,都要先放下HTML的解析工作,等待JavaScript代码加载、执行完才能继续(点这里查看为什么)
因此:
- 如果外联的JavaScript文件太大,加载速度慢,对不起,解析工作推后;
- 如果JavaScript代码执行耗时,对不起,解析工作推后。
解析推后直接后果就是,我们看到网页的时间也推后,直观后果是白屏时间变长。
所以,不管将<script>
标签写在<body>
标签末尾,还是采用defer属性,都是在解决HTML文档的解析阻塞问题。
算时间
结合上面的Performance API我们就知道,duration = loadEventEnd - start
貌似就是我们需要的指标时间,是这样么?
不是的。
样式文件、媒体资源的加载不会阻塞渲染进程的主线程。这么说时间应该是domInteractive - start
?
不好意思,也不对。
样式文件的加载,是不影响文档解析。但是,如果页面中同时外联CSS和JavaScript文件的时候,浏览器会等待所有外联CSS下载完成并转成CSSOM后,才继续执行脚本。
为什么?因为JavaScript具备操作CSSOM的能力,这就形成了依赖关系。
所以,虽然CSS的网络加载请求不会阻塞文档解析,但是由于上述原因,必须等待页面中所有外联CSS资源下载完并转换成CSSOM之后,才会继续解析文档。
这么一说,时间是domContentLoadedEvent - start
?
不好意思,还不对。。。
我们上面说,navigation是从上个页面执行unload回调开始,到当前页面完成DOM解析和资源加载这个过程为止,这个过程还包括了向服务器请求并收到服务器响应数据、资源这个过程。我们需要刨除掉这段时间,才能算出从开始解析完。那这段时间怎么算?在下篇文章中分析~