浏览器的渲染过程
- 把 html 文档解析成一棵 DOM 树
- 把 css 文档解析成一棵 css 规则树
- DOM 树和 CSS 规则树组成一棵 render 渲染树,然后就根据这个渲染树开始绘制页面
绘制过程会有两种情况,一种是重绘,一种是回流
重绘是和外观有关系,一般是 color,background-color 回流是和布局、尺寸、显示隐藏相关的 一般和带有 px 相关的
回流一定会重绘,重绘不一定回流
频繁的重绘和回流 尤其是回流会导致页面变慢,所以要尽量减少页面重绘和回流
优化的思路
- 浏览器本身自己的优化 UI 渲染是异步的,它会把所有要绘制放在一个队列中,等到了一定的时间间隔才会一次性批处理绘制
- 我们可以做的优化:我们要减少重绘和回流就是要减少对渲染树的操作,则我们可以合并多次的 DOM 和样式的修改
- 尽量不要使用一堆的行内样式操作,而是把要操作的全部写在类 clas 中,然后直接调用这个类名
- 在操作之前先把这块 display:none;然后把所有的操作全部做完,然后再 display:block,这样只会有两次重绘和回流
- 使用克隆元素的技术,实现复用
- 在写动画的时候可以用脱离文档流,避免对文档其他地方有影响
8. 使用 DocumentFragment 文档碎片(不要直接在 DOM 树上操作,而是先搞一个文档碎片,在这个文档碎片上把所有的操作全部做完,在这个文档碎片上做的任何操作不会触发重绘和回流,因为和 DOM 树没有关系,等操作全部搞定,再把这个文档碎片追加到 DOM 树上,只会导致一次重绘和回流)
<script>
// 没有使用文档碎片之前的写法,会导致101次重绘和回流
var ul = document.createElement('ul')
document.body.append(ul)
for(var i=0;i<100;i++){
var li = document.createElement('li')
li.innerHTML = i;
ul.append(li)
}
</script>
<script>
// 只有一次重绘和回流
var documentFragment = document.createDocumentFragment();
var ul = document.createElement("ul");
documentFragment.append(ul);
for (var i = 0; i < 100; i++) {
var li = document.createElement("li");
li.innerHTML = i;
ul.append(li);
}
document.body.append(documentFragment);
</script>