在以前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中,和你们分享了从在浏览器中输入网址URL到最终页面展现的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰,因此本文就浏览器渲染流程单独开篇讲解,但愿你们都能有新的收获。javascript
(浏览器主要组件)css
Firefox使用Geoko——Mozilla自主研发的渲染引擎。html
Safari和Chrome都使用webkit。Webkit是一款开源渲染引擎,它原本是为linux平台研发的,后来由Apple移植到Mac及Windows上。java
本文我主要以webkit渲染引擎来说解,尽管webkit和Gecko使用的术语稍有不一样,他们的主要流程基本相同。linux
(webkit渲染引擎流程)git
关键渲染路径是指浏览器从最初接收请求来的HTML、CSS、javascript等资源,而后解析、构建树、渲染布局、绘制,最后呈现给客户能看到的界面这整个过程。程序员
因此浏览器的渲染过程主要包括如下几步:github
解析HTML生成DOM树。web
解析CSS生成CSSOM规则树。segmentfault
将DOM树与CSSOM规则树合并在一块儿生成渲染树。
遍历渲染树开始布局,计算每一个节点的位置大小信息。
将渲染树每一个节点绘制到屏幕。
当浏览器接收到服务器响应来的HTML文档后,会遍历文档节点,生成DOM树。
须要注意的是,DOM树的生成过程当中可能会被CSS和JS的加载执行阻塞。渲染阻塞问题下文会讲。
浏览器解析CSS文件并生成CSS规则树,每一个CSS文件都被分析成一个StyleSheet对象,每一个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其余对象。
当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行,而后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,若是JavaScript脚本还操做了CSSOM,而正好这个CSSOM尚未下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。
因此,script 标签的位置很重要。实际使用时,能够遵循下面两个原则:
CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JS置后:咱们一般把JS代码放到页面底部,且JavaScript 应尽可能少影响 DOM 的构建。
当解析html的时候,会把新来的元素插入dom树里面,同时去查找css,而后把对应的样式规则应用到元素上,查找样式表是按照从右到左的顺序去匹配的。
例如: div p {font-size: 16px},会先寻找全部p标签并判断它的父标签是否为div以后才会决定要不要采用这个样式进行渲染)。
因此,咱们平时写CSS时,尽可能用id和class,千万不要过渡层叠。
经过DOM树和CSS规则树咱们即可以构建渲染树。浏览器会先从DOM树的根节点开始遍历每一个可见节点。对每一个可见节点,找到其适配的CSS样式规则并应用。
渲染树构建完成后,每一个节点都是可见节点而且都含有其内容和对应规则的样式。这也是渲染树与DOM树的最大区别所在。渲染树是用于显示,那些不可见的元素固然就不会在这棵树中出现了,譬如。除此以外,display等于none的也不会被显示在这棵树里头,可是visibility等于hidden的元素是会显示在这棵树里头的。
布局阶段会从渲染树的根节点开始遍历,而后肯定每一个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每一个元素在屏幕内的确切位置与大小。
在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工做是由浏览器的UI后端组件完成的。
根据渲染树布局,计算CSS样式,即每一个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:replaint和reflow。
replaint:屏幕的一部分重画,不影响总体布局,好比某个CSS的背景色变了,但元素的几何尺寸和位置不变。
reflow: 意味着元件的几何尺寸变了,咱们须要从新验证并计算渲染树。是渲染树的一部分或所有发生了变化。这就是Reflow,或是Layout。
因此咱们应该尽可能减小reflow和replaint,我想这也是为何如今不多有用table布局的缘由之一。
display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,因此visibility:hidden 只会触发 repaint,由于没有发生位置变化。
有些状况下,好比修改了元素的样式,浏览器并不会马上 reflow 或 repaint 一次,而是会把这样的操做积攒一批,而后作一次 reflow,这又叫异步 reflow 或增量异步 reflow。
有些状况下,好比 resize 窗口,改变了页面默认的字体等。对于这些操做,浏览器会立刻进行 reflow。
本文咱们就浏览器渲染流程逐步了解了一遍,相信你们必定都有所新的收获,若是你们对于浏览器渲染流程还有任何疑问,欢迎反馈,咱们共同交流,共同窗习,共同进步。
最后,欢迎关注个人公众号:程序员专区。里面有N多干货,技术分享、IT资讯……。留言100%回复,有问必答。 不想提高技术的(ban)码(yun)农(gong)就别来了,内容过于专业~
参考文献:
sylvanassun.github.io/2017/10/03/…