news 2026/9/28 2:54:58

重排、重绘、合成:浏览器渲染的“三兄弟”,你惹不起也躲不过

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
重排、重绘、合成:浏览器渲染的“三兄弟”,你惹不起也躲不过

你给一个元素悄悄改了宽度,结果整个页面都抖了一下?你加了个动画,电脑风扇开始狂转?今天我们来认识浏览器渲染里的“三兄弟”——重排、重绘、合成。弄懂它们,你就能写出流畅60帧的页面,告别卡顿。

前言

想象一下,你家客厅要重新装修。你只是换了个抱枕(重绘),很轻松。但如果你要把墙拆了(重排),那得搬家具、砸墙、重新粉刷,累得半死。如果只是把电视画面换个图层(合成),连工人都不要,遥控器一按就行。

浏览器的渲染也是这个道理。理解这三种操作的成本,就能写出性能飞起的页面。

一、先复习:渲染流水线

之前我们讲过,浏览器把HTML/CSS变成屏幕上的像素,要经过:DOM树 + CSSOM树 → 渲染树 → 布局(计算位置大小)→ 绘制(填充像素)→ 合成(合并图层)。

其中:

  • 重排(Reflow):重新计算布局(位置、大小)。成本最高。
  • 重绘(Repaint):重新绘制像素(颜色、背景、阴影等)。成本中等。
  • 合成(Composite):重新合并图层。成本极低(走GPU)。

二、重排:动到筋骨,全员遭殃

什么操作会触发重排?

  • 改变元素的几何属性:width、height、margin、padding、border、top、left……
  • 改变DOM结构:增删元素、改变内容(文字变了导致高度变化)。
  • 读取某些布局属性:offsetTop、scrollTop、clientWidth、getComputedStyle()。因为浏览器需要返回最新值,不得不强制重排。
  • 改变窗口大小(resize事件)。
  • 激活伪类(如:hover导致样式变化影响布局)。

重排的代价:浏览器要重新计算整个或部分渲染树,然后重新布局、绘制、合成。就像你拆了一面墙,整个房子都得重新量尺寸。

三、重绘:只换皮肤,不动骨架

什么操作会触发重绘但不触发重排?

  • 改变颜色:color、background-color、border-color、box-shadow等。
  • 改变可见性:visibility(但display: none会触发重排)。
  • 改变背景图、outline等。

重绘的代价:不需要重新布局,但还是要重新绘制像素,比重排轻,但也不是免费。

四、合成:GPU加速的“超车道”

合成是成本最低的环节,因为它不涉及布局和绘制,只把已有的图层合并。能触发合成的属性有:

  • transform(平移、旋转、缩放)
  • opacity
  • filter

当你用transform: translateZ(0)或will-change: transform时,浏览器会把这个元素提升到单独的合成层,后续动画只由GPU处理,完全不触发重排和重绘。这就是为什么动画推荐用transform而不是left。

/* 差:触发重排 */.box{transition:left 0.3s;left:0;}.box:hover{left:100px;}/* 好:只触发合成 */.box{transition:transform 0.3s;transform:translateX(0);}.box:hover{transform:translateX(100px);}

五、如何减少重排和重绘?

1. 批量修改样式

不要挨个改属性,用class一次改完:

// 差element.style.width='100px';element.style.height='100px';element.style.margin='10px';// 好element.classList.add('new-size');

2. 让元素脱离文档流再操作

比如要插入多个li,可以先隐藏(display: none),改完再显示,只触发两次重排。

constul=document.getElementById('list');ul.style.display='none';for(leti=0;i<1000;i++){constli=document.createElement('li');li.textContent=i;ul.appendChild(li);}ul.style.display='block';

3. 使用文档片段(DocumentFragment)

constfragment=document.createDocumentFragment();for(leti=0;i<1000;i++){constli=document.createElement('li');li.textContent=i;fragment.appendChild(li);}ul.appendChild(fragment);// 只触发一次重排

4. 读写分离

不要交替读取和修改布局属性,否则会触发多次重排。

// 差for(leti=0;i<boxes.length;i++){boxes[i].style.width=boxes[i].offsetWidth+'px';// 读后立即写}// 好:先读后写constwidths=[];for(leti=0;i<boxes.length;i++){widths.push(boxes[i].offsetWidth);}for(leti=0;i<boxes.length;i++){boxes[i].style.width=widths[i]+'px';}

5. 使用transform和opacity做动画

永远不要用left、top、width、margin做动画,改用transform。

6. 固定元素位置

position: fixed或absolute的元素,其重排影响范围较小(只在自己层内)。

7. 避免使用table布局

一个小改动可能触发整个table的重排。

六、实战:一个性能优化的例子

假设你要做一个跟随鼠标移动的小光点(类似鼠标特效)。错误做法:每帧改变top/left,触发重排。正确做法:用transform。

// 差:每移动1px就重排一次dot.style.left=x+'px';dot.style.top=y+'px';// 好:只触发合成dot.style.transform=`translate(${x}px,${y}px)`;

七、怎么分析页面重排/重绘?

Chrome DevTools → Performance 面板,录制一段操作,查看“Layout Shift”、“Paint”等标记。红色紫色区域越少越好。

八、总结:三兄弟的“饭量”

  • 重排:吃满汉全席,最贵。动几何、DOM结构。
  • 重绘:吃快餐,中等。动颜色、背景。
  • 合成:喝矿泉水,几乎免费。动transform、opacity。

优化口诀:能用transform别用left,能用class别改style,读写分离,批量操作。

如果你觉得今天的“三兄弟”够形象,点个赞让更多人看到。明天我们将聊聊JavaScript引擎与内存管理,看看V8是怎么给代码“打扫卫生”的。我们明天见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 7:52:12

昇腾300I NPU实战:从零部署BGE-M3 Embedding模型并构建本地向量服务

1. 昇腾300I NPU与BGE-M3模型初探 最近在折腾昇腾AI处理器的模型部署&#xff0c;发现用昇腾300I NPU跑BGE-M3 Embedding模型效果相当不错。这个组合特别适合需要本地化部署向量服务的场景&#xff0c;比如企业内部的知识库检索或者隐私敏感数据的处理。先说说为什么选择这个方…

作者头像 李华
网站建设 2026/9/18 3:04:04

JavaEE实战:腾讯会议云录制功能在编程考试中的合规应用指南

1. 为什么编程考试需要云录制&#xff1f; 最近几年线上编程考试越来越普及&#xff0c;但监考一直是个头疼的问题。我参与过多次高校JavaEE考试的监考工作&#xff0c;发现传统录屏方式存在三大痛点&#xff1a;一是本地录屏文件容易被篡改&#xff0c;二是视频体积大传输困难…

作者头像 李华
网站建设 2026/9/21 17:10:33

Akagi终极指南:用AI麻将助手提升雀魂水平,快速成为麻将高手

Akagi终极指南&#xff1a;用AI麻将助手提升雀魂水平&#xff0c;快速成为麻将高手 【免费下载链接】Akagi 支持雀魂、天鳳、麻雀一番街、天月麻將&#xff0c;能夠使用自定義的AI模型實時分析對局並給出建議&#xff0c;內建Mortal AI作為示例。 Supports Majsoul, Tenhou, Ri…

作者头像 李华
网站建设 2026/9/18 19:44:15

Windows平台终极ADB和Fastboot驱动一键安装完整指南

Windows平台终极ADB和Fastboot驱动一键安装完整指南 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirrors/la/Latest-adb-fast…

作者头像 李华