回流(reflow)与重绘(repaint)
作者:互联网
介绍下回流(reflow)与重绘(repaint)
1.了解浏览器的渲染机制
- 浏览器采用流式布局模型。
- 首先浏览器会将HTML解析成DOM,把CSS解析成CSSOM,把CSSOM与DOM结合产生render tree。
- 有了render tree之后,我们知道了节点样式,然后浏览器会计算节点的位置,然后把节点绘制到页面上。
总结:回流一定会引起重绘,重绘不一定会引起回流。
2.回流
- 当我们render tree中的一些元素的结构或者尺寸发生改变,浏览器会重新渲染部分或者全部的文档流,这个过程就叫做回流。
会导致回流的操作:
- 页面首次渲染
- 浏览器窗口大小发生变化
- 内容变换
- 添加或者删除节点
- 激活CSS伪类
- clinentWidth/offWidth
3.重绘
- 当页面中元素样式的改变不影响它在文档流中的位置,浏览器会将新样式赋予给元素,这个过程就叫做重绘。
会导致重绘的操作:
- background
- visibility:隐藏后文档流中任保留空间。
4.性能影响
总结:回流的性能消耗要比重回大
5.避免性能影响
CSS:
- 避免使用table布局:Table会阻挡浏览器渲染引擎的渲染顺序。(会延迟页面的生成速度,让用户等待更久的时间。)
- 避免设置多层内联样式
JavaScript:
- 避免频繁使用DOM操作
- 对于大量插入DOM的操作,建议使用文档片段,也就是documentFragment
思考:
使用绝对定位会引起回流么?
- 改变绝对定位会引起回流,因为设置absolute的元素在标准流当中将不占据位置,浏览器会重新渲染部分或者全部的文档流。
补充:documentFragment
DocumentFragment
,文档片段接口
与document相比,最大的区别是DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。
例子
HTML
<ul id="list"></ul>
JavaScript
const list = document.querySelector('#list');
const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];
const fragment = document.createDocumentFragment();
fruits.forEach(fruit => {
const li = document.createElement('li');
li.innerHTML = fruit;
fragment.appendChild(li);
});
list.appendChild(fragment);
- Apple
- Orange
- Banana
- Melon
标签:repaint,浏览器,reflow,DOM,渲染,文档,回流,重绘 来源: https://blog.csdn.net/TiAmopanduola/article/details/123232568