动画卡顿主因是使用width/left等触发重排的属性,应改用transform/opacity实现GPU加速;阶梯式动画靠animation-delay编排;@keyframes优先用from/to;无限动画须用class控制启停。

动画性能卡顿,是因为用了 width 或 left 动画
用 width、left、top 做 Loading 动画,浏览器每次都要重排(reflow),帧率容易掉到 30fps 以下。真实项目里只要看到加载动画“抖”或“卡”,八成是动了布局属性。
正确做法只用 transform 和 opacity:它们触发的是合成层(Compositor)渲染,走 GPU 加速,60fps 很稳。比如旋转用 transform: rotate(),上下跳用 transform: translateY(),淡入淡出用 opacity。
- 避免写
animation: moveLeft 1s infinite;+@keyframes moveLeft { to { left: 100px; } } - 改成
animation: slide 1s infinite;+@keyframes slide { to { transform: translateX(100px); } } - 如果必须控制宽度(如进度条),确保父容器
overflow: hidden,且仅在必要时用will-change: width提前提示浏览器
阶梯式/波浪式动画,靠 animation-delay 错开时机
多个点依次弹起、条形逐级上升、波纹层层扩散——这类效果不是靠 JS 控制,而是用 CSS 的 animation-delay 手动编排时间轴。每个元素延迟值递增,就能形成自然的节奏感。
关键点在于延迟单位要统一用 s 或 ms,别混用;且延迟值最好基于总周期计算,比如总动画时长 1.2s,3 个点就设 0s、0.4s、0.8s,避免后期调参混乱。
立即学习“前端免费学习笔记(深入)”;
.dot:nth-child(1) { animation-delay: 0s; }.dot:nth-child(2) { animation-delay: 0.3s; }.dot:nth-child(3) { animation-delay: 0.6s; }- 如果用 JS 动态插入元素,记得给新元素也加上对应延迟,否则节奏会断
@keyframes 里用 from/to 比 0%/100% 更安全
某些旧版 Safari(iOS 12 及更早)对 0% 和 100% 解析不稳定,尤其在配合 animation-fill-mode: forwards 时,可能最后一帧不生效。用 from / to 是兼容性更稳妥的选择。
另外,多关键帧动画(比如弹跳+缩放)别堆在单个 @keyframes 里硬凑,拆成独立动画分别挂载,方便复用和调试。例如一个齿轮既要自转又要公转,就定义 spin 和 orbit 两个动画,再用 animation: spin 1s infinite, orbit 3s infinite 同时应用。
- 推荐写法:
@keyframes bounce { from { transform: translateY(0); } to { transform: translateY(-20px); } } - 避免写法:
@keyframes bounce { 0% { transform: translateY(0); } 50% { transform: translateY(-20px); } 100% { transform: translateY(0); } }(除非真需要中间停顿) - 动画名别用中文或特殊符号,只用字母、数字、短横线,比如
loading-pulse可以,loading_脉冲会报错
无限循环动画停不下来,得靠 class 切换控制
CSS 动画一旦设了 infinite,它就真“无限”了——没有内置暂停/停止机制。实际业务中,Loading 状态总有开始和结束,不能靠删元素或改 display 来关,那会触发重排。
标准解法是用 class 控制:初始加 is-loading 触发动画,数据就绪后移除该 class,再配合 animation-play-state: paused 或直接清空 animation 值。注意别漏掉 vendor prefix,比如 -webkit-animation-play-state 在 iOS Safari 仍需保留。
- HTML:
<div class="spinner is-loading"></div> - CSS:
.spinner.is-loading { animation: spin 1s linear infinite; } - JS:
el.classList.remove('is-loading');(自动停掉动画) - 如果要用 JS 暂停而非停止,可临时加
style.animationPlayState = 'paused',但记得恢复时设回'running'


















