一、什么是回流与重排
1.回流
通过构造渲染树,将可见DOM节点以及它对应的样式结合起来,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流。
重排&&重绘
浏览器下载完页面所有的资源后,就要开始构建DOM树,
于此同时还会构建渲染树(Render Tree)。(其实在构建渲染树之前,
和DOM树同期会构建Style Tree。DOM树与Style Tree合并为渲染树)
DOM树
表示页面的结构
渲染树
表示页面的节点如何显示
一旦渲染树构建完成,就要开始绘制(paint)页面元素了。当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。简单的说,重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘
二. 容易造成回流的操作
-
布局流相关操作
- 盒模型的相关操作会触发重新布局
- 定位相关操作会触发重新布局
- 浮动相关操作会触发重新布局
-
改变节点内的内容
改变节点的结构或其中的文本结构会触发重新布局
3.css
宽高、边框、边框距,定位、居中、加粗…
三、容易造成重绘的操作css
- color
- border-style
- border-radius
- text-decoration
- box-shadow
- outline
- background
四、减少回流和重绘
合并样式修改
减少造成回流的次数,如果要给一个节点操作多个css属性,而每一个都会造成回流的话,尽量将多次操作合并成一个例子:
var oDiv = document.querySelector('.box');
oDiv.style.padding = '5px';
oDiv.style.border = '1px solid #000';
oDiv.style.margin = '5px'
操作div的3个css属性,分别是padding、border、margin,此时就可以考虑将多次操作合并为一次。
方法一:使用style的cssText:
oDiv.style.cssText = 'padding:5px; border:1px solid #000; margin:5px;';
方法二:将这几个样式定义给一个类名,然后给标签添加类名:
<style>
.pbm{
padding:5px;
border:1px solid #000;
margin:5px;
}
</style>
<script>
var oDiv = document.querySelector('.box');
oDiv.classList.add('pbm');
</script>