重排(reflow)与重绘(repaint)

260 阅读2分钟

浏览器从下载文件至本地到显示页面是个复杂的过程,这里包含了重绘和重排。通常来说,渲染引擎会解析HTML文档来构建DOM树,与此同时,渲染引擎也会用CSS解析器解析CSS文档构建CSSOM树。接下来,DOM树和CSSOM树关联起来构成渲染树(RenderTree),这一过程称为Attachment。然后浏览器按照渲染树进行布局(Layout),最后一步通过绘制显示出整个页面。

一、概念

重排:当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。

重绘:完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。

注意:重排一定会触发重绘,而重绘不一定会****重排(例如改变元素的背景色)

二、什么时候发生重排和重绘

重排:

  • 添加和或者删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括:外边距,内边距,边框厚度,宽度,高度等属性发生改变)
  • 内容发生变化(例如:内容增加引起高度变化或者是图片被另外一个不同尺寸的图片所替换)
  • 页面渲染器进行初始化的
  • 浏览器窗口尺寸发生改变

重绘:

  • 元素的可见的外观被改变,但并没有影响到布局的时候。比如,仅修改DOM元素的字体颜色(只有Repaint,因为不需要调整布局)

三、如何减少重排和重绘

重绘和重排操作都是代价昂贵的操作,它们会导致web应用程序的UI反应迟钝,所以应该尽可能减少这类过程的发生。

  • 合并多次对DOM和样式的修改
  • 将多次重排的元素设为absolute或者fixed,这样元素就脱离了文档流,他的变化不会影响到其他元素,比如有动画效果的元素
  • 由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂操作时,可以先隐藏他,操作完成之后在显示,这样只会在影藏和显示的时候触发2次重排。
  • 在需要经常取的,引起浏览器重排的属性值时,要缓存到变量
  • 图片载入的时候设置宽高