will-change - 性能优化
提前告知浏览器哪些属性将要变化
什么是 will-change?
will-change 是一个性能优化属性,它告诉浏览器某个元素的哪些属性即将发生变化,让浏览器提前做好优化准备。
- 作用:提前创建图层,启用硬件加速
- 目的:让动画更流畅,减少卡顿
- 注意:不要滥用,会消耗额外内存
语法说明
will-change: auto | property-name;
- auto - 默认值,浏览器自动决定
- transform - 告知 transform 属性将变化
- opacity - 告知 opacity 属性将变化
- left, top - 告知位置属性将变化
- scroll-position - 告知滚动位置将变化
- 可以指定多个属性:will-change: transform, opacity
使用示例
/* 1. 悬停时会变换的元素 */
.card {
will-change: transform;
transition: transform 0.3s;
}
.card:hover {
transform: translateY(-10px);
}
/* 2. 持续动画的元素 */
.loading-spinner {
will-change: transform;
animation: spin 1s linear infinite;
}
/* 3. 多个属性 */
.animated-element {
will-change: transform, opacity;
}
性能对比演示
悬停查看效果(实际性能差异在复杂动画中更明显)
未优化
悬停我
无 will-change
已优化
悬停我
will-change: transform
示例:复杂动画优化
持续运行的复杂动画,使用 will-change 优化
优化
.animated-box {
will-change: transform;
animation: complexMove 3s ease-in-out infinite;
}
@keyframes complexMove {
0%, 100% {
transform: translate(0, 0) rotate(0deg);
}
25% {
transform: translate(100px, 0) rotate(90deg);
}
50% {
transform: translate(100px, 50px) rotate(180deg);
}
75% {
transform: translate(0, 50px) rotate(270deg);
}
}
⚠️ 使用注意事项
警告:不要滥用 will-change!过度使用会消耗大量内存,反而降低性能
✅ 正确使用
- 只在确实需要优化的元素上使用
- 用于频繁变化或复杂动画的元素
- 动画结束后移除 will-change
- 不要在 CSS 中全局设置
❌ 错误使用
- 给所有元素都加上 will-change
- 设置 will-change: all(性能很差)
- 在不需要动画的元素上使用
- 动画结束后不移除
最佳实践
/* 方式 1:CSS 中设置(适合持续动画) */
.loading-spinner {
will-change: transform;
animation: spin 1s linear infinite;
}
/* 方式 2:JavaScript 动态设置(推荐) */
element.style.willChange = 'transform';
// 执行动画...
element.addEventListener('transitionend', () => {
element.style.willChange = 'auto'; // 动画结束后移除
});
推荐:对于交互触发的动画(如悬停),在 mouseenter 时设置 will-change,在 mouseleave 或动画结束时移除
何时使用 will-change?
- ✅ 复杂的 transform 动画(多个变换组合)
- ✅ 持续运行的动画(如加载动画)
- ✅ 频繁触发的交互动画
- ✅ 大量元素同时动画(如列表项)
- ✅ 3D 变换动画
- ❌ 简单的悬停效果(浏览器已自动优化)
- ❌ 一次性的简单动画
- ❌ 静态元素