重排(reflow)和重绘(repaint)是浏览器渲染的一个过程,并且十分影响性能,让我们先来看看浏览器网页渲染的全过程
浏览器如何渲染网页
浏览器渲染网页主要分为以下五步
1.浏览器将获取的HTML文档解析成DOM树。
2.处理CSS标记,构成层叠样式表模型CSSOM(CSS Object Model)。
3.将DOM和CSSOM合并为渲染树(rendering tree
),代表一系列将被渲染的对象。
4.渲染树的每个元素包含的内容都是计算过的,它被称之为布局layout
。浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有的元素。
5.将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting
。
我们都知道HTML默认是流式布局的,但CSS和JS会打破这种布局,改变DOM的外观样式以及大小和位置。因此就出现了重绘和重排
重排 | 回流(reflow)
触发条件
当浏览器发现布局发生了变化,这个时候就需要倒回去重新渲染,这个回退的过程叫reflow
。
简单来说就是渲染树中的节点大小、位置等信息发生了改变,需要重新计算,重新渲染。
会引起重排的条件:
1.页面第一次渲染(初始化)
2.DOM树节点增删或移动
3.一个 DOM 元素的几何属性变化,常见的几何属性有width
、height
、padding
、margin
、left
、top
、border
4.浏览器窗口resize
5.获取元素的某些属性,比如offset
族、scroll
族和client
族属性
reflow
几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会reflow
哪一部分的代码,因为他们会相互影响。
重排过程
reflow
会从html
这个root frame
开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树。
相当于是将解析和合成的过程重新走了一遍,开销很大。
重绘(repaint)
触发条件
repaint是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。
1.reflow
回流必定引起repaint
重绘,重绘可以单独触发。
2.背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)
重绘过程
由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,从而省去布局的过程。流程如下:
避免重排、重绘
1.用transform
做形变和位移可以减少reflow
2.避免逐个修改节点样式,尽量一次性修改
3.使用DocumentFragment
将需要多次修改的DOM元素缓存,最后一次性append
到真实DOM中渲染
4.可以将需要多次修改的DOM元素设置display:none
,操作完再显示。(因为隐藏元素不在render
树内,因此修改隐藏元素不会触发回流重绘)
5.避免多次读取某些属性
6.通过绝对位移将复杂的节点元素脱离文档流,形成新的Render Layer,降低回流成本