主题
重排重绘
重排(reflow)
1、概念
根据渲染树中每个渲染对象的信息,计算出各自渲染对象的几何信息(DOM对象的位置和尺寸大小),并将其安置在界面中的正确位置。
2、会引起重排的操作
- 页面首次渲染。
- 浏览器窗口大小发生改变。
- 元素尺寸或位置发生改变。
- 元素内容变化(文字数量或图片大小等等)。
- 添加或者删除可见的 DOM 元素。
- 激活 CSS 伪类(例如::hover)
3、影响范围
- 全局范围:从根节点
html
开始对整个渲染树进行重新布局 - 局部范围:对渲染树的某部分或某一个渲染对象进行重新布局
- 把一个dom的宽高之类的几何信息定死,然后在dom内部触发重排
重绘(repaint)
概念
当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程
优化
1、读写操作分离
- 多次写操作会被放进渲染队列中,一次性渲染
- 但读操作会导致写操作提前进行渲染
js
// 一次重排
div.style.left = '10px';
div.style.top = '10px';
js
// 两次重排
div.style.left = '10px';
console.log(div.offsetLeft); // 即便读操作和写操作没有任何关系
div.style.top = '10px';
2、样式集中改变
- 渲染队列
js
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
- className
js
div.classList.add('name');
- cssText
js
const left = 10, top = 10;
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
3、离线改变 DOM
display:none
- 在操作 DOM 前,先隐藏,操作完成后,再让它显示出来,这样只会发生一次重排
- 使用
DocumentFragment
批量生成 DOM 后,再插入文档中 - 复制节点,操作完成后,再替换
4、绝对定位
让节点的定位是 fixed
或 absolute
,这样操作时,能只进行局部重排,减少开销
5、优化动画
- 动画使用绝对定位,每一次移动尽可能多的像素距离
- 开启
Gpu
加速- transitions、transform 3d
分析重排重绘
使用 chrome devtool
帮助分析