透过performance探究js操作dom样式时浏览器会做什么?

目录

浏览器对回流(重排)、重绘的优化策略

透过performance探究js操作dom样式时浏览器会做什么?

如果只是读取“敏感”属性,没有对节点进行几何改变,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记录

透过performance探究js操作dom样式时浏览器会做什么?

透过performance探究js操作dom样式时浏览器会做什么?

js执行之后进行样式计算、布局、更新分层树、绘制、合成

比上一个多了一个布局步骤

测试情况

设置有关元素几何(位置、尺寸等)的属性
btn.onclick = () => {
    div.style.height = '100px';
}
设置有关元素几何(位置、尺寸等)的属性并读取该元素的非“敏感”样式属性
btn.onclick = () => {
    div.style.height = '100px';
    const { color, width, height } = div.style;
}

performance记录

透过performance探究js操作dom样式时浏览器会做什么?
透过performance探究js操作dom样式时浏览器会做什么?

浏览器在js执行期间进行样式计算

样式计算后,如果有新的样式设置,会将其放到“渲染优化队列”中

读取“敏感”属性

btn.onclick = () => {
    const top = div.scrollTop,
      width = div.clientWidth;
};

performance记录

透过performance探究js操作dom样式时浏览器会做什么?

读取“敏感”属性后并设置无关节点几何位置的样式

btn.onclick = () => {
    const top = div.scrollTop;
    div.style.color = 'red';
    div.style.backgroundColor = 'blue';
};

performance记录

透过performance探究js操作dom样式时浏览器会做什么?

读取“敏感”属性后并设置有关节点几何位置的样式

btn.onclick = () => {
    const top = div.scrollTop;
    div.style.color = 'red';
    div.style.height = '100px';
};

performance记录

透过performance探究js操作dom样式时浏览器会做什么?

读取“敏感”属性后并设置无关节点几何位置的样式,之后再次读取“敏感”属性

浏览器会执行两次样式计算

btn.onclick = () => {
    const clientHeight = div.clientHeight;
    div.style.color = 'red';
    const clientWidth = div.clientWidth;
};

performane记录

透过performance探究js操作dom样式时浏览器会做什么?

读取“敏感”属性后并设置有关节点几何位置的样式,之后再次读取“敏感”属性

浏览器会在js执行期间进行两次样式计算并强制同步布局。

btn.onclick = () => {
    const clientHeight = div.clientHeight;
    div.style.height = '100px';
    const clientWidth = div.clientWidth;
};

performane记录

透过performance探究js操作dom样式时浏览器会做什么?

与节点的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记录

透过performance探究js操作dom样式时浏览器会做什么?

关于window.getComputedStyle()

透过performance探究js操作dom样式时浏览器会做什么?

结论

  1. 网上说的推荐使用class少用style操作dom可以减少浏览器的一些操作(样式计算、强制同步布局等),减少性能消耗
  2. 网上说的操作style时,读写分离,先读后写,也可以减少一些样式计算的性能消耗
  3. 没事儿不要用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

上一篇:MySQL锁(读锁、写锁、表锁、行锁)


下一篇:selenium 记录 performance日志