🔥 一、CSS 为什么会影响性能?
浏览器渲染页面的流程:
- Style 计算(样式计算)
- Layout(回流 / 重排)
- Paint(重绘)
- Composite(合成层)
CSS 写得不好,会导致:
- 样式计算变慢
- 回流频繁(性能杀手)
- 重绘开销大
- 强制同步 layout(卡顿)
- 层叠规则复杂导致匹配慢
🚨 二、CSS 性能杀手(重点)
1. 复杂的选择器
尤其是:
div div div span classul 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-ratioflexgridcontain
特别推荐使用 contain
告诉浏览器“这里的布局不会影响外面”:
.card {
contain: layout;
}
能大幅减少 Layout 范围。