本文不会介绍整个前端渲染过程的步骤,只是记录最近阅读的文章的些许思考和感悟。(文章地址一(系列),文章地址二)html
但愿你们在阅读这篇文章以前能将上述文章仔细浏览一篇,由于本文所述基本是基于其内容。前端
Navigation Timing API:可经过打印(performance)查看;git
浏览器加载事件:domContentLoaded,onloadgithub
上图整理了Navigation Timing API中的一些事件和浏览器加载事件的发生顺序。web
这些事件的含义是什么呢?咱们直接引用文章地址一(系列)的介绍:chrome
domContentLoaded:表示 DOM 准备就绪而且没有样式表阻止 JavaScript 执行的时间点,这意味着如今咱们能够构建渲染树了。浏览器
看了上述事件的介绍,大体了解了每一个事件所表明的含义,但也带着少量疑惑:框架
首先看第一个问题,咱们直接用chrome控制台的performance来看效果。dom
上图中,上方的Network的蓝条是HTML的下载时间,下方箭头所指是HTML的解析时间。async
从中咱们能够得出HTML解析的确是分批进行,而且解析并不须要等HTML彻底下载完。那为何要分批进行呢?这个问题我找了许多资料也没有得出结论,因而本身从中思考。假设不是分批进行,那实现会有两种状况:1.等HTML所有下载完,再一块儿解析;2.每下载必定量的HTML就将其放入解析器等待排队解析。前者首先确定被排除,若HTML很大,会影响首屏加载速度,后者按理速度更快,或许其实现的难度以及可能会带来的一些问题而没有采用?这个问题思考了良久,感受从理论上是可行的,但从技术角度,因为本身这方面的知识实在薄弱,因此也没法得知其实现的过程是否存在技术瓶颈。
第二个问题:CSSOM树构建是否在domContentLoaded事件以前?
话很少说咱们本身实践。
首先我先建立一个HTML文件并写入少量标签,再建立一个CSS并于HTML引入,在CSS文件中写入大量内容(本身实践时写了5W多行)。而后用performance查看。
上图每一个箭头表明的含义:
从这个步骤以及其所处时间,咱们能够清晰的得出,该结论不许确。那么该做者为何会得出该结论呢,是他犯错了吗?我随后发现他在这篇文章下面还写了一句“domContentLoaded通常表示DOM和CSSOM均准备就绪的时间点”。那么这句话意味着大部分的时候CSSOM树的构建是在domContentLoaded事件以前。但是这个大部分又指的是什么状况,这又涉及到另外一个知识点“DOM树,CSSOM树,JS的三角关系”,构造DOM树时碰见JS会先解析执行JS,而在解析执行JS时遇到CSSOM,又会先构造CSSOM树,这个过程稍后会具体说明。那么如今咱们能够明白这个问题的关键所在了,由于在大部分页面中是拥有JS的,而因为其解析顺序,那么在domContentLoaded事件以前一定已经成功构造CSSOM树。
第三个问题:domInteractive与domContentLoaded的区别是什么呢?这两个事件中间是否还会进行其余操做?
咱们都知道script标签有defer和async两个属性。有了这两个属性,浏览器就会加一个进程下载JS。那么下载完的执行时间点是在何时?其中async会在JS下载完后立马执行,也正是这个缘由,会致使JS的执行顺序不必定按标签的从上至下,而是按照下载完的时间。那么defer属性的执行时间呢,我想你们应该都能猜到了,它的执行时间点的确就是在上述的两个事件之间,那么咱们也就得知这两个事件的区别所在。
咱们都知道前端渲染有三大树:DOM树,CSSOM树,RENDER树。那么这三大树的构造时间和上述的事件执行时间的顺序又是怎样的呢。
其中DOM树和RENDER树所在位置实际上是显而易见的,而且在以前内容也已经指出。DOM树在domInteractive事件以前,RENDER树在domContentLoaded事件以后。可是CSSOM树就难以捉摸,其与DOM树的关系,彻底受到是否拥有JS影响。
在肯定CSSOM树所处位置前,咱们先肯定一个上面提到的概念:构造DOM树时碰见JS会先解析执行JS,而在解析执行JS时遇到CSSOM,又会先构造CSSOM树。官方给出的缘由是,JS会使用document.write而改变DOM树,因此构造DOM树时碰到JS会先执行JS;而JS在执行时,须要查找CSS,因此执行JS时,碰到构造CSSOM树,会先构造CSSOM树。可是这里有一点奇怪的时,JS也能够经过创造Link标签的方式改变CSSOM树,因此我的感受官方的这种解释有点牵强。不过官方的解释虽然不能让人彻底信服,但这执行顺序是不会有错的。
接下来咱们分别经过有无JS两大类确认CSSOM树所处位置:
可是有2个有意思的状况:
(1) 若是咱们动态建立link标签并添加到html中,那么又会发生什么呢?若JS还没解析执行完,那么会中止JS而去解析CSS,若JS已执行完那么CSSOM树其实也不是一定在domInteractive以前。(固然这可能已经不算初次渲染构建)
(2) link标签放到JS后面又会发生什么呢?这种状况我发现无论我怎么尝试,CSSOM树一定在DOM树构建以前构建,但其又在JS执行完成后。若是有兴趣的同窗能够查查是为何。
其实前端渲染是一个很庞大的知识点,而且其涉及的周边知识也及其庞大,本文只是对其中一个小知识点作了思考和实践。最后要说的一点是,以上内容,纯属我的看法,若有不当,请多指教。