- 浏览器对回流(重排)、重绘的优化策略
- 测试环境
- 测试代码
- 设置节点的style时浏览器的多种处理情况
- 与节点的class相关的浏览器处理操作
- 关于window.getComputedStyle()
- 结论
- 来源
浏览器对回流(重排)、重绘的优化策略
如果只是读取“敏感”属性,没有对节点进行几何改变,js执行期间仅会进行样式计算,不会强制布局。
测试环境
Chrome 版本 96.0.4664.45(正式版本) (64 位)
测试代码
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="div">
<div></div>
</div>
<button>点击测试</button>
<script>
const div = document.getElementById('div');
const btn = document.querySelector('button');
btn.onclick = () => {
// do something
};
</script>
</body>
</html>
设置节点的style时浏览器的多种处理情况
仅观察代码中btn
点击事件附近相关的浏览器处理
浏览器在js执行期间什么都不做
js执行之后进行样式计算、更新分层树、绘制、合成
测试情况
点击事件中没有代码
btn.onclick = () => {
// do something
};
设置无关元素几何(位置、尺寸等)的属性
btn.onclick = () => {
div.style.color = 'red';
};
设置无关元素几何(位置、尺寸等)的属性并读取该元素的一些样式属性
btn.onclick = () => {
div.style.color = 'red';
const { color, width, height } = div.style;
}
performance记录
js执行之后进行样式计算、布局、更新分层树、绘制、合成
比上一个多了一个布局步骤
测试情况
设置有关元素几何(位置、尺寸等)的属性
btn.onclick = () => {
div.style.height = '100px';
}
设置有关元素几何(位置、尺寸等)的属性并读取该元素的非“敏感”样式属性
btn.onclick = () => {
div.style.height = '100px';
const { color, width, height } = div.style;
}
performance记录
浏览器在js执行期间进行样式计算
样式计算后,如果有新的样式设置,会将其放到“渲染优化队列”中
读取“敏感”属性
btn.onclick = () => {
const top = div.scrollTop,
width = div.clientWidth;
};
performance记录
读取“敏感”属性后并设置无关节点几何位置的样式
btn.onclick = () => {
const top = div.scrollTop;
div.style.color = 'red';
div.style.backgroundColor = 'blue';
};
performance记录
读取“敏感”属性后并设置有关节点几何位置的样式
btn.onclick = () => {
const top = div.scrollTop;
div.style.color = 'red';
div.style.height = '100px';
};
performance记录
读取“敏感”属性后并设置无关节点几何位置的样式,之后再次读取“敏感”属性
浏览器会执行两次样式计算
btn.onclick = () => {
const clientHeight = div.clientHeight;
div.style.color = 'red';
const clientWidth = div.clientWidth;
};
performane记录
读取“敏感”属性后并设置有关节点几何位置的样式,之后再次读取“敏感”属性
浏览器会在js执行期间进行两次样式计算并强制同步布局。
btn.onclick = () => {
const clientHeight = div.clientHeight;
div.style.height = '100px';
const clientWidth = div.clientWidth;
};
performane记录
与节点的class相关的浏览器处理操作
浏览器在js执行期间什么也不做。所以这就是网上说的使用class
样式减少对节点style
的操作?
.style {
color: red;
height: 100px;
}
btn.onclick = () => {
const className = div.className;
div.className = `style`;
// 或者下面的代码
/*
div.classList.add('style');
const className = div.classList.toString();
*/
};
performance记录
关于window.getComputedStyle()
结论
- 网上说的推荐使用class少用style操作dom可以减少浏览器的一些操作(样式计算、强制同步布局等),减少性能消耗
- 网上说的操作style时,读写分离,先读后写,也可以减少一些样式计算的性能消耗
- 没事儿不要用window.getComputedStyle()获取样式
来源
https://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
https://dl.acm.org/doi/10.1145/1772690.1772741
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/getComputedStyle