核心是分离读写、缓存布局值、避免强制同步布局;频繁交替读写DOM几何属性(如offsetTop、clientWidth)会触发链式重排,应先批量读取再批量写入,优先用transform/opacity和CSS类名控制样式。

核心在于分离读与写、缓存访问结果、避免强制同步布局。DOM 属性的频繁交替读写是隐藏最深的性能杀手之一,尤其在循环中触发 offsetTop、clientWidth、scrollHeight 等布局信息时,浏览器会立即执行同步重排(forced reflow),开销远超普通 JS 运行。
把读操作和写操作彻底分开
不要在一个循环里边读边改,否则每次“读”都会迫使浏览器把上一次“写”的结果立刻计算出来,形成链式重排。
- 先遍历一遍,集中读取所有需要的布局值(如
elem.offsetTop、elem.getBoundingClientRect()),存入数组或对象 - 再遍历一遍,用缓存的值批量设置样式,优先使用
transform和opacity,它们不触发布局,只走合成层 - 示例中用
translateX替代left,就是为绕过重排;用getBoundingClientRect一次性拿到全部位置信息,比多次读offsetTop高效得多
缓存 DOM 查询和布局值,别重复找、别重复算
每次调用 document.getElementById、element.style 或 elem.offsetHeight,都可能引发额外开销。尤其是后者,在循环中反复调用等于主动拖慢页面。
- 把
document.querySelector('.list')的结果赋给变量,后续直接复用,而不是每次都要从头查 - 如果需要多次获取同一元素的
scrollTop或clientWidth,只取一次,后面全用这个值 - 对动态变化的值(如滚动位置),可在
requestAnimationFrame回调里统一读取,避免帧内多次取值
用现代 API 和 CSS 类替代内联样式操作
直接写 elem.style.color = 'red' 或 elem.style.left = '100px' 不仅难维护,还容易意外触发重排。浏览器必须同步验证样式是否影响布局,而类名切换是声明式的、可预编译的。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 把样式逻辑写进 CSS,例如
.is-active { transform: translateX(20px); } - 用
elem.classList.add('is-active')切换状态,不碰style对象 - 需要动画时,用
requestAnimationFrame控制更新节奏,而不是setTimeout或setInterval
警惕那些看似无害的“读取”操作
以下属性只要被访问,就可能触发同步布局——哪怕你只是想看看它多高:
-
offsetTop、offsetLeft、offsetWidth、offsetHeight -
clientTop、clientLeft、clientWidth、clientHeight -
scrollWidth、scrollHeight、scrollTop、scrollLeft -
getComputedStyle(elem)(尤其是读取几何相关属性时)
如果真要读,确保它不在写操作之后紧邻出现;更稳妥的做法是,把这些读取挪到 requestAnimationFrame 的回调开头,让浏览器有机会合并渲染任务。


















