作移动web页面,受移动网络网速和终端性能影响,咱们常常要关注首屏内容展现时间(如下简称首屏时间)这个指标,它衡量着咱们的页面是否能在用户耐心消磨完以前展现出来,很大程度影响着用户的使用满意度。css
咱们常常要先问本身:页面是怎么加载数据?html
A:加载完静态资源后经过ajax请求去后台获取数据,数据回来后渲染内容web
在每一个点打上一个时间戳,首屏时间 = 点8 – 点1;ajax
B:使用后台直出,返回的html已经带上内容了chrome
此时首屏时间 = 点4 – 点1。浏览器
注:1. 打了这么多个点,是由于当咱们收集到首屏时间以后,要去分析究竟是哪一段是性能瓶颈,哪一段还有优化空间,因此咱们须要收集 点2 – 点一、点3 – 点1 ……这些时间以做分析;性能优化
2. 打点1咱们通常是在html文件head标签的开头打个时间戳;服务器
3. 在css文件加载前通常没有别的加载处理,因此打点1和打点2通常能够合并。网络
到此咱们就收集到首屏相关各类数据,能够作各类针对性优化。Wait!在你大刀阔斧优化前,你要了解一些细节,它们有利于你作更准确的分析和更细致的优化。dom
JsEndTime – JsStartTime = js文件的加载时间,对吗?
不对!明显地,这个等式忽略了js的执行时间。js执行代码是须要花费时间的,特别是作一些复杂的计算或频繁的dom操做,这个执行时间有时会达到几百毫秒。
那么,JsEndTime – JsStartTime = js文件的加载执行时间?
依然不对!由于CSS文件的加载执行带来了干扰。以为很奇怪对吧,别急,咱们来作个试验:咱们找一个demo页面,在chrome里面打开,而后启动控制台,模拟低网速,让文件加载时间比较久:
先在正常状况下收集 JsEndTime – JsStartTime 的时间,而后使用fiddler阻塞某一条css请求几秒钟:
而后再恢复请求,拿到此时的 JsEndTime – JsStartTime 结果,会发现第一次的时间是几百毫秒将近1s,而第二次的时间低于100ms甚至接近为0(个人示例,时间视读者具体的js文件决定),二者的差距很是明显。
这是什么原理?这就是咱们常说的”加载是并行的,执行是串行的“的结果。html开始加载的时候,浏览器会将页面外联的css文件和js文件并行加载,若是一个文件还没回来,它后面的代码是不会执行的。刚刚咱们的demo,咱们阻塞了css文件几秒,此时js文件由于并行已经加载回来,但因为css文件阻塞住,因此后面 JsStartTime 的赋值语句是不执行的!当咱们放开阻塞,此时才会运行到 JsStartTime 的赋值、js文件的解析、JsEndTime的赋值,因为大头时间加载早已完成,因此 JsEndTime 和 JsStartTime 的差值很是小。
知道这个有何用?
固然,那两个打点留着仍是能够作分析用的。
前半部分的结论在细节1里面已经证实,由于浏览器的执行是串行的。这说明,咱们负责渲染内容的js代码要等到它前面全部的js文件加载执行完才会执行,即便那些代码跟渲染无关的代码如数据上报:
然后半部分的结论很好验证,咱们在负责渲染的js文件后面外联一个别的js文件并把它阻塞住,你会发现渲染相关的js不论是动态拉取新的js文件、拉取渲染相关内容都一切正常,页面内容顺利渲染出来,它们的执行并不须要等被阻塞的这个文件。
知道这个有何用?
(注:我的以为这是全文最重要的两点结论,由于我正在作首屏优化^-^)
打点1通常写在html里head标签的最前面,时常有朋友拿直出时的 点4 – 点1 的时间和非直出时 点8 – 点1 的时候作对比,来讲明直出优化了多少多少毫秒,我倒以为不必定。要知道直出的状况html文件包含渲染后的内容和dom节点,文件大小通常比非直出大,有时甚至大个几十K都有,那我以为要说明直出优化了多少就要把html的加载时间考虑进去了。那上面的计算方法是否考虑上html的加载时间?
那就要看html文件的返回头是否包含chunk:
若是包含这个返回头,那html文件是边返回边解析的,此时上面的计算方法是合理的。若是不包含这个头,则html文件是整一个返回来后才开始解析,此时上面的计算方法就少算了html的加载时间,也就不够精准。这个返回头是由后台控制的。
知道这个有何用?
咱们有时会用 domContentLoaded 事件代替 onload 事件,在页面准备好的时候作一些处理。然而要知道,domContentLoaded里面的dom不止包含咱们常说的普通dom节点,还包括script节点。
试验一下,咱们将页面里面外联的一个js文件阻塞住一段时间再放开,咱们看下chrome控制台:
很明显,js文件的加载时间会影响这个事件的触发事件。那js代码的解析时间会不会影响?咱们在最后一个外联js文件后面打了一个点,它的时间是:
因此js文件加载执行会影响domContentLoaded事件的执行时机。
知道这个有何用?
研究首屏时间和资源加载是一件挺有意思的事情,你们利用好chrome控制台(特别是里面的network标签)以及fiddler能够挖掘出不少有趣的小细节小结论。别觉得这是在没事找事,理解好这些对你们作首屏性能优化、定位由于js文件执行顺序错乱致使报错等场景是很是有好处的。因此发现什么记得与我共享哈~