🔥 一、CSS 为什么会影响性能?
浏览器渲染页面的流程:
-
Style 计算(样式计算)
-
Layout(回流 / 重排)
-
Paint(重绘)
-
Composite(合成层)
CSS 写得不好,会导致:
-
样式计算变慢
-
回流频繁(性能杀手)
-
重绘开销大
-
强制同步 layout(卡顿)
-
层叠规则复杂导致匹配慢
🚨 二、CSS 性能杀手(重点)
1. 复杂的选择器
尤其是:
-
div div div span class -
ul li:first-child:not(.active) -
body * -
:not(),:nth-child()大量使用
这些会增加浏览器的 Selector Matching 时间。
❌ 不推荐:
.container ul li span.active {}
✔️ 推荐:
.item-title.active {}
2. 使用通配符或深层选择器
-
* -
body * -
.container *
这些会匹配大量节点。
3. 频繁触发 Layout(回流) 的 CSS 属性
以下属性会导致 回流:
| 触发回流的属性 | 示例 |
|---|---|
| width / height | 改尺寸 |
| padding / margin | 布局变化 |
| border | 大小改变 |
| position / top / left | 位置改变 |
| font-size / line-height | 字体变化 |
| display | none → block |
大量 DOM + 高频操作时会卡顿。
4. 导致重绘(Paint)频繁的属性
包括:
-
background
-
box-shadow(大阴影)
-
border-color
-
color
-
outline
特别是 动画中使用 box-shadow 非常耗性能。
5. 高代价 CSS 动画
对 非复合层属性 做动画:
❌ 慎用动画:
-
left / top
-
width / height
-
background
-
box-shadow
✔️ 优化:使用 GPU-friendly 属性:
-
transform
-
opacity
动画只通过 合成层 执行 → 非常快
6. 未合理创建合成层
以下内容最好放到单独合成层:
-
高频动画(变换、淡入淡出)
-
fixed 元素
-
拖拽元素
可用:
will-change: transform;
或:
transform: translateZ(0);
7. 大量无用的 CSS(未使用的样式)
大型项目中常见:样式文件几十 KB 甚至数百 KB
→ 加载慢 → 解析慢 → 样式计算慢
8. 复杂布局:table、float
-
<table>会触发更多次 layout -
float 布局复杂且容易触发回流
🧭 三、CSS 优化方案(最实用)
🔧(1)优化选择器
✔️ 保持选择器短、避免深层级
建议不超过 3 层
/* bad */
.container .list ul li span.title {}
/* good */
.item-title {}
🔧(2)避免低效选择器
-
避免 body *
-
避免过度使用 :not、:nth-child
🔧(3)减少回流(Layout)触发
高频操作使用 transform
❌ 不要这样做(每一帧触发回流):
.left-moving {
left: 100px;
}
✔️ 改成 transform:
.left-moving {
transform: translateX(100px);
}
🔧(4)减少重绘(Paint)
-
避免大面积 box-shadow
-
背景渐变、blur 慎用
-
使用
opacity+transform做动画
🔧(5)将动画提升为独立合成层
.animate {
will-change: transform, opacity;
}
注意:不要乱用 will-change(会占 GPU 内存)。
用于真正频繁动画才好。
🔧(6)降低 CSS 文件体积
-
Tree-shaking / PurgeCSS / uncss
-
删除无用样式
-
组件化(CSS Modules / Tailwind / Styled Components)
🔧(7)避免强制同步布局(JS + CSS 的问题)
以下 JS 操作会触发浏览器"马上计算布局":
element.offsetHeight
element.offsetTop
getComputedStyle(element).width
避免:
div.style.height = '100px';
console.log(div.offsetHeight); // 强制布局
🔧(8)减少使用 table 和 float 布局
优先使用:
-
flex
-
grid
性能好、计算简单。
🔧(9)使用更现代的 CSS(Layout 优化)
比如:
-
aspect-ratio -
flex -
grid -
contain
特别推荐使用 contain
告诉浏览器"这里的布局不会影响外面":
.card {
contain: layout;
}
能大幅减少 Layout 范围。