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 变换动画
  • ❌ 简单的悬停效果(浏览器已自动优化)
  • ❌ 一次性的简单动画
  • ❌ 静态元素