浏览器在收到 HTML, CSS, JS 文件后,它是如何把页面呈现到屏幕上的?
下图对应的就是WebKit渲染的过程。
浏览器是一个边解析边渲染的过程:
DOM > CSSOM > 渲染树 > 布局 > 绘制
① 浏览器解析HTML文件构建DOM树,然后解析CSS文件构建CSS规则树
② DOM树和CSS规则树解析完成后,合成渲染树(Render Tree)
③ 等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上(重排和重绘)。
HTML:理解成一个框架模型,经历:字节>字符>Token>节点>DOM
- HTML解释器:解释HTML语言的解释器,本质是将HTML文本解释成DOM树(文档对象模型)。
CSS:理解成装修,经历:link标签>字节>字符>Token>节点>CSSOM
- CSS解释器:解释样式表的解释器,其作用是将DOM中的各个元素对象加上样式信息,从而为计算最后结果的布局提供依据。
渲染树:任务是匹配DOM和CSSOM的节点,并且捕获可见内容
布局:意思就是获取渲染树的结果、节点位置和大小,是依据盒子模型来进行的
- 布局:将DOM和CSS样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型即渲染树。
- JavaScript引擎:JavaScript可以修改网页的内容,也能修改CSS的信息,JavaScript引擎解释JavaScript代码并把代码的逻辑和对DOM和CSS的改动信息应用到布局中去,从而改变渲染的结果。
绘制:把渲染树以像素的形式绘制在页面上
CSSOM不能部分解析,DOM可以部分解析
总结:
浏览器发送请求以后,服务器或者本地返回给浏览器HTML文件,这个时候第一步就是解析HTML文件,并且构建DOM树。
在解析HTML文件的时候遇到了link标签,浏览器就去请求CSS文件,请求CSS文件的同时也继续解析HTML文件。
此时遇到了script标签,浏览器就去请求JS文件,服务器或者本地就会陆续返回CSS和JS文件,实际操作中会先得到CSS还是JS是要看具体情况的。
如果先返回并且解析完成JS文件也是会发生阻塞,我们不能先执行JS文件,必须等到CSSOM构建完成了才能执行JS文件。(因为渲染树是需要DOM和CSSOM构建完成了才能构建,而且JS是可以操作CSS样式的)所以这一步是解析CSS文件构建并且CSSOM。
JS是会阻塞HTML解析的,因为JS既可以操作DOM,又可以操作CSSOM,如果不等JS下载解析执行完再构建DOM,那有可能导致网页的有些内容出现了又消失。如果JS设置了async,也就是异步执行,那就不会阻塞HTML解析。
JS执行完成之后,就正常了,构建DOM树以及构建渲染树。然后进行布局和绘制。
注意:
浏览器在解析过程中,如果遇到请求外部资源时,如图像,iconfont,JS等。请求过程是异步的,并不会影响HTML文档进行加载。但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。
原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。
绘制这个过程比较复杂,涉及到两个概念: reflow(重排)和repain(重绘)。