面试题库 词条目录
前端Wiki/面试题库/HTTP 与浏览器/浏览器高频题

重绘回流与性能优化

重绘(repaint):元素外观改变(颜色、背景)但几何不变,重新绘制像素。回流(reflow / layout):几何信息(宽高、位置)改变,需要重新布局整棵或局部渲染树。回流的开销远大于重绘,且回流几乎必然带来重绘 —— 所以“回流是性能杀手”。

常见触发回流的操作:改 width / height / margin、窗口 resize、读写 offsetWidth 等强制同步布局属性(布局抖动)、批量改 DOM 结构。优化手段:用 transform / opacity 做动画(走合成层,不触发布局);批量 DOM 操作用 DocumentFragment 或先 display: none 脱离文档流;读写分离(先读够所有布局信息再统一写);防抖 resize 监听。

  • 重绘改外观、回流改几何;回流必然带重绘,开销是重绘的数倍
  • transform / opacity 动画走合成层,不触发回流
  • 读写分离 + 批量操作 + 防抖 resize,是三大实战手段
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
  .box { width: 80px; height: 80px; background: #f0c33c; border-radius: 8px;
         transition: transform .3s; }   /* transform 动画:合成层,不回流 */
  .bad { transition: left .3s; position: relative; left: 0; }  /* left 动画会回流 */
</style>
</head>
<body>
  <button onclick="move1()">好:transform</button>
  <button onclick="move2()">差:left + 强制布局</button>
  <div class="box" id="b1">A</div>
  <div class="box bad" id="b2">B</div>
  <script>
    function move1() {                          // 推荐写法
      document.getElementById('b1').style.transform = 'translateX(200px)';
    }
    function move2() {                          // 反面:改几何 + 读写交织
      const el = document.getElementById('b2');
      el.style.left = el.offsetLeft + 200 + 'px';   // 读布局又写布局 → 布局抖动
    }
    // 批量插入 100 个节点:用 DocumentFragment 只回流一次
    function batch() {
      const frag = document.createDocumentFragment();
      for (let i = 0; i < 100; i++) {
        const li = document.createElement('li');
        li.textContent = '项 ' + i;
        frag.appendChild(li);                    // 先在内存里拼好
      }
      document.body.appendChild(frag);           // 一次回流
    }
    // 动画统一交给 rAF,与浏览器刷新率对齐
    function rafAnim() {
      const el = document.getElementById('b1');
      requestAnimationFrame(() => { el.style.transform = 'translateX(300px)'; });
    }
  </script>
</body>
</html>
本节要点重绘改色回流改形;优化核心 = 用 transform/opacity 替代几何动画 + 批量 DOM + 读写分离。
🔗 相关词条CSSJavaScriptJS 特效