MST

星途 面试题库

面试题:JavaScript 批量修改 DOM 样式的性能优化

在一个拥有大量 DOM 元素(比如 1000 个)的页面中,需要批量修改它们的样式,从性能角度考虑,如何优化 JavaScript 代码以减少重排和重绘的次数?请详细说明优化思路并给出示例代码。
10.9万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 优化思路

    • 批量操作:避免逐个修改 DOM 元素样式,而是一次性对多个元素进行样式更改。可以先将元素从文档流中移除(例如使用 display:none 使元素不可见,这样操作元素不会触发重排重绘),然后批量修改样式,最后再将元素放回文档流或恢复其可见性。
    • 使用类名:通过修改类名来改变样式,因为修改类名只会触发一次重排重绘,而直接修改多个样式属性可能会多次触发。
    • 读写分离:避免在获取元素的布局信息(如 offsetWidthclientHeight 等)后紧接着修改样式,因为读取布局信息会强制浏览器进行重排以返回最新的值。
  2. 示例代码

    • 使用 display:none 批量操作样式
<!DOCTYPE html>
<html>

<head>
    <style>
        /* 定义需要切换的样式类 */
       .new - style {
            color: red;
            font - size: 20px;
        }
    </style>
</head>

<body>
    <div id="parent">
        <!-- 假设这里有1000个div元素 -->
        <div>Element 1</div>
        <div>Element 2</div>
        <div>Element 3</div>
        <!-- 省略更多div -->
    </div>
    <script>
        const parent = document.getElementById('parent');
        const children = parent.children;
        // 隐藏父元素,避免重排重绘
        parent.style.display = 'none';
        for (let i = 0; i < children.length; i++) {
            children[i].classList.add('new - style');
        }
        // 恢复父元素可见
        parent.style.display = 'block';
    </script>
</body>

</html>
  • 使用类名切换样式
<!DOCTYPE html>
<html>

<head>
    <style>
       .original - style {
            color: black;
            font - size: 16px;
        }
       .new - style {
            color: red;
            font - size: 20px;
        }
    </style>
</head>

<body>
    <div id="parent">
        <div class="original - style">Element 1</div>
        <div class="original - style">Element 2</div>
        <div class="original - style">Element 3</div>
        <!-- 假设这里有1000个div元素 -->
    </div>
    <script>
        const elements = document.querySelectorAll('.original - style');
        for (let i = 0; i < elements.length; i++) {
            elements[i].classList.remove('original - style');
            elements[i].classList.add('new - style');
        }
    </script>
</body>

</html>