html的重绘与重排(回流)

浏览器的运行机制

  1. 构建DOM树,渲染引擎解析html文档,首先将标签解析成dom树中的dom node(包括js生成的标签),生成内容树(Content Tree/ Dom Tree);
  2. 构建渲染树(construct),解析对应的css文件(包括js生产的样式和外部引入的样式文件),而这些文件信息以及html中可见的指令例如(
    ),构成渲染树(rendering tree /frame tree),render tree中每个节点都有对应的 style,不包括隐藏的节点(例display: none;)还有head 节点,因为这些节点不会用于呈现。
  3. 布局渲染树(reflow/layout),从根节点递归调用,计算每一个元素大小、位置等,给出节点在屏幕出现的精确坐标。
  4. 绘制渲染树(paint/repaint),遍历渲染树,使用ui层来绘制每个节点。

**重绘(redraw/repaint)**

当盒子的位置大小以及其他属性,例如颜色、字体大小等都确定下来之后,浏览器便会把这些原色都按照各自的特性绘制一遍,将内容呈现在页面上。

重绘是一个元素外观改变触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

触发重绘发生的条件是改变元素外观属性,如:color, background-color等

注意:table以及内部元素可能需要多次计算才能确定其在渲染树中节点的属性值,比同等元素要多花两倍时间,这就是我们尽量避免使用table布局页面的原因之一。

**重排(reflow/回流)**

当渲染树中的一部分(或者全部)因为元素的规模尺寸,布局和隐藏等改变需要重新构建,这就称为回流。每个页面至少需要一次回流,就是在页面开始加载的时候。

重绘与重排的关系:在回流的时候浏览器会使渲染树中受到影响的部分失效,并重新构建这部分渲染树。完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。

所以重排必定会重绘,重绘不一定会重排。

触发重排的条件,任何页面布局几何属性的改变都会触发重排,如:

  1. 页面渲染初始化(无法避免)
  2. 添加或删除可见dom元素
  3. 元素位置改变,或者使用动画
  4. 元素尺寸大小的改变,如大小,边框,外边框
  5. 浏览器窗口尺寸的 变化(resize事件发生时)
  6. 填充内容的改变,例如文本的改变或者图片大小的改变而引起的计算值宽度和高度的改变
  7. 读取某些元素属性(宽高之类的值)

问题扩展

优化:

  1. 浏览器自己的优化,浏览器会维护一个队列,把所有会引起回流,重绘的操作放到队列里面,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会flush队列,进行一个批处理,这样就会让多次的回流重绘变成一次的回流重绘。
  2. 我们要注意的优化:我们要减少重绘和重排就是要减少对渲染树的操作,则我们可以合并多次的dom和样式的修改,并减少对style样式的请求。
  • 直接改变元素的className
  • display: none;先设置元素为display: none; 然后进行页面布局等操作,操作完成后将元素设置为dispaly: block;这样的话只引发两次回流与重绘
  • 使用cloneNode(true or false)和repalceChild技术引发一次回流与重绘
  • 将需要多次重排的元素,position属性设为absolute或fixed,元素脱离了文档流,他的变化不会影响其他元素
  • 如果需要创建多个dom节点,可以使用documentFragment创建完成后一次性的加入document

 

你可能感兴趣的:(html)