🏠 故事开始:浏览器的装修日记
想象你正在装修房子:
布局(Layout)= 设计图纸(确定家具位置和大小)重排(Reflow)= 突然决定把沙发从客厅搬到卧室(所有家具位置都要重新计算)重绘(Repaint)= 给墙壁换颜色(家具位置不变,只是表面刷新) 今天我们就通过 一些简单的代码,聊聊这两个让前端开发者又爱又恨的概念。
🚀 代码里的性能陷阱
反面教材:让CPU崩溃的JS动画
先看代码:
let width = 0;
function move() {
width += 2;
box.style.width = width + 'px'; // 每次修改都会触发重排
if(width < 300) {
requestAnimationFrame(move);
}
}
这段代码通过不断修改 width 属性实现动画,就像你每分钟都要重新测量房间大小——浏览器会疯狂执行:
- 计算盒子新尺寸( 重排 )
- 重新绘制像素( 重绘 )
- 重复上述步骤...
优化尝试:CSS Transition的救赎
再看改进代码:
.box {
transition: left 1s ease-out; /* 比JS动画更聪明 */
}
.box.active {
left: 300px; /* 仍然会触发重排 */
}
虽然CSS过渡比JS动画高效,但修改 left 属性依然会触发重排。就像你虽然请了装修公司,但还是要天天改设计图。
💡 性能优化的黄金法则
我们一一来揭秘,其实浏览器有个隐藏福利:
transform和opacity属性不会触发重排!
它们就像给元素开了VIP通道,直接交给GPU处理,跳过布局计算环节。把上面的代码改成这样:
.box.active {
/* left: 300px; */ /* 👈 这是青铜玩家的做法 */
transform: translateX(300px); /* 👑 这是王者操作 */
}
🕵️♂️ 如何检测重排和重绘?
-
打开 Chrome DevTools(开发者工具)。
- 右键点击页面并选择 “检查” (Inspect),或者使用快捷键
Ctrl+Shift+I(Windows/Linux)或Cmd+Opt+I(Mac)。
- 右键点击页面并选择 “检查” (Inspect),或者使用快捷键
-
转到 “Performance” 面板。
- 在DevTools界面顶部的标签中,选择 Performance 标签。
-
启用 Paint flashing:
- 在 Performance 面板中,点击右上角的 三个垂直点(更多选项),然后选择 “Settings” 。
- 在设置面板中,找到 “Rendering” 部分,勾选 “Paint flashing” 选项。
-
启用 Layout Shift Regions
- 在 “Rendering” 同样找到 Layout Shift Regions,勾选上。
-
启用后,浏览器会在页面绘制时以闪烁的方式显示出每次重绘的区域,帮助你分析页面渲染的性能瓶颈。
勾选 Paint flashing(重绘区域会闪烁绿色)
勾选 Layout Shift Regions(重排区域会闪烁蓝色)
试试用这个方法对比 文章的第一段代码 和优化后的版本,你会看到明显差异!
三次结果分别对比
🛠️ 前端性能优化工具箱
- 批量
DOM操作 :先离线修改DOM,再一次性更新 - 使用
BFC:隔离布局影响(就像给房间装隔断) will-change: transform:提前告诉浏览器"我要动了!"- 避免强制同步布局 :不要在读取
offsetHeight后立即修改样式
总结:重绘重排防坑指南
记住: 重排是性能杀手,重绘是帮凶,transform是你的超级英雄!
下次写动画时,想想浏览器这个装修工的苦衷——少改图纸(重排),多刷油漆(重绘),实在不行就用VIP通道(transform)!
💬 互动话题:你遇到过哪些因为重排导致的性能问题?评论区分享你的踩坑经历吧!