浏览器渲染过程

浏览器渲染主要流程

(webkit渲染引擎流程)

所以可以分析出基本过程:

  1. 解析HTML生成DOM树。

  2. 解析CSS生成CSSOM规则树。

  3. 将DOM树与CSSOM规则树合并在一起生成渲染树。

  4. 遍历渲染树开始布局,计算每个节点的位置大小信息。

  5. 计算好的信息绘制整个页面

HTML解析

举个例子:一段HTML

<html>
<head>
    <title>Web page parsing</title>
</head>
<body>
    <div>
        <h1>Web page parsing</h1>
        <p>This is an example Web page.</p>
    </div>
</body>
</html>

经过解析之后的DOM Tree差不多就是

CSS解析

浏览器解析CSS文件并生成CSS规则树,每个CSS文件都被分析成一个StyleSheet对象,每个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其他对象。

渲染阻塞

浏览器解析文档,当遇到<script>标签的时候,会立即解析脚本,停止解析文档(因为JS可能会改动DOM和CSS,所以继续解析会造成浪费)。
如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。现在可以在script标签上增加属性 defer(ie)或者async
脚本解析会将脚本中改变DOM和CSS的地方分别解析出来,追加到DOM树和规则树上。

如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。

所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:

CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。

构建渲染树

通过DOM树和CSS规则树我们便可以构建渲染树。浏览器会先从DOM树的根节点开始遍历每个可见节点。对每个可见节点,找到其适配的CSS样式规则并应用。

渲染树构建完成后,每个节点都是可见节点并且都含有其内容和对应规则的样式。这也是渲染树与DOM树的最大区别所在。渲染树是用于显示,那些不可见的元素当然就不会在这棵树中出现了,譬如。除此之外,display等于none的也不会被显示在这棵树里头,但是visibility等于hidden的元素是会显示在这棵树里头的。

 

渲染树布局

布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。

渲染树绘制

在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。

布局Layout

根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:repaint和reflow。
repaint:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。
reflow: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。
所以我们应该尽量减少reflow和repaint,我想这也是为什么现在很少有用table布局的原因之一。
 

display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。

有些情况下,比如修改了元素的样式,浏览器并不会立刻 reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。
有些情况下,比如 resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

下面这些动作有很大可能会是成本比较高的:

  • 当你增加、删除、修改DOM结点时,会导致Reflow或Repaint

  • 当你移动DOM的位置,或是搞个动画的时候。

  • 当你修改CSS样式的时候。

  • 当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候。

  • 当你修改网页的默认字体时。

  • 注:display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化。

基本上来说,reflow有如下的几个原因:

  • Initial。网页初始化的时候。

  • Incremental。一些Javascript在操作DOM Tree时。

  • Resize。其些元件的尺寸变了。

  • StyleChange。如果CSS的属性发生变化了。

  • Dirty。几个Incremental的reflow发生在同一个frame的子树上。

Chrome调试工具查看页面渲染顺序

页面的渲染详细过程可以通过chrome开发者工具中的timeline查看

 

  1. 发起请求;

  2. 解析HTML;

  3. 解析样式;

  4. 执行JavaScript;

  5. 布局;

  6. 绘制

页面渲染优化

浏览器对上文介绍的关键渲染路径进行了很多优化,针对每一次变化产生尽量少的操作,还有优化判断重新绘制或布局的方式等等。
在改变文档根元素的字体颜色等视觉性信息时,会触发整个文档的重绘,而改变某元素的字体颜色则只触发特定元素的重绘;改变元素的位置信息会同时触发此元素(可能还包括其兄弟元素或子级元素)的布局和重绘。某些重大改变,如更改文档根元素的字体尺寸,则会触发整个文档的重新布局和重绘,据此及上文所述,推荐以下优化和实践:

  1. HTML文档结构层次尽量少,最好不深于六层;

  2. 脚本尽量后放,放在前即可;

  3. 少量首屏样式内联放在标签内;

  4. 样式结构层次尽量简单;

  5. 在脚本中尽量减少DOM操作,尽量缓存访问DOM的样式信息,避免过度触发回流;

  6. 减少通过JavaScript代码修改元素样式,尽量使用修改class名方式操作样式或动画;

  7. 动画尽量使用在绝对定位或固定定位的元素上;

  8. 隐藏在屏幕外,或在页面滚动时,尽量停止动画;

  9. 尽量缓存DOM查找,查找器尽量简洁;

  10. 涉及多域名的网站,可以开启域名预解析

参考链接

浏览器渲染页面过程与页面优化

【干货】十分钟读懂浏览器渲染流程

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值