关于 gsap-performance
面向 GSAP 开发者的动画性能优化技能,汇总减少布局与绘制开销、控制并发动画及处理滚动动画的实践。
主要功能
- 01优先使用变换和透明度
- 02批量执行布局读写
- 03用 stagger 管理多元素动画
- 04用 gsap.quickTo() 处理频繁更新
- 05清理离屏动画与 ScrollTrigger
适用场景
- 01排查动画卡顿与掉帧
- 02优化长列表的动画表现
- 03实现鼠标跟随动画
- 04调整 ScrollTrigger 性能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nexu-io/ open-design --skill gsap-performance安装后在 Claude Code 中输入/gsap-performance确认已加载。
附带文件LICENSESOURCES.md
详细介绍
GSAP 性能
整理自 GreenSock 官方 GSAP skills:https://github.com/greensock/gsap-skills
何时使用此技能
在优化 GSAP 动画以实现流畅的 60fps、降低布局/绘制开销,或用户询问性能、卡顿或快速动画的最佳实践时使用。
相关技能: 使用 gsap-core(变换、autoAlpha)和 gsap-timeline 构建动画;有关 ScrollTrigger 性能,请参阅 gsap-scrolltrigger。
优先使用 Transform 和 Opacity
为 transform(x、y、scaleX、scaleY、rotation、rotationX、rotationY、skewX、skewY)和 opacity 添加动画,可以让工作由合成器处理,避免布局和大部分绘制。若使用变换可以实现相同效果,就避免为布局开销大的属性添加动画。
- ✅ 优先使用:x、y、scale、rotation、opacity。
- ❌ 尽可能避免:width、height、top、left、margin、padding(它们会触发布局,并可能导致卡顿)。
GSAP 的 x 和 y 默认使用变换(translate);移动元素时请用它们代替 left/top。
will-change
对即将添加动画的元素使用 CSS will-change。它会提示浏览器提升图层。
will-change: transform;
批量读取和写入
GSAP 会在内部批量处理更新。当 GSAP 与直接 DOM 读写或依赖布局的代码混用时,应避免交错读取和写入,以免反复触发布局抖动。最好先完成所有读取,再进行所有写入(或让 GSAP 一次性处理写入)。
大量元素(Stagger、列表)
- 当动画相同时,使用 stagger 代替多个带手动延迟的独立补间动画;这样效率更高。
- 对于较长的列表,可以考虑使用虚拟化或只为可见项添加动画;如果会导致卡顿,请避免同时创建数百个补间动画。
- 尽可能复用时间轴;避免每帧都创建新时间轴。
频繁更新的属性(例如鼠标跟随元素)
对于频繁更新的属性(例如鼠标跟随元素的 x/y),优先使用 gsap.quickTo()。它会复用单个补间动画,而不是每次更新都创建新的补间动画。
let xTo = gsap.quickTo("#id", "x", { duration: 0.4, ease: "power3" }),
yTo = gsap.quickTo("#id", "y", { duration: 0.4, ease: "power3" });
document.querySelector("#container").addEventListener("mousemove", (e) => {
xTo(e.pageX);
yTo(e.pageY);
});
ScrollTrigger 与性能
- pin: true 会提升固定元素的图层;只固定必要的元素。
- 使用较小的 scrub 值(例如
scrub: 1)可以减少滚动期间的工作量;请在低端设备上测试。 - 仅在布局实际变化时(例如内容加载后)调用 ScrollTrigger.refresh(),不要在每次调整大小时都调用;尽可能使用防抖。
减少同时执行的工作
- 当画面外或非活动动画不可见时,请暂停或终止它们(例如用户离开页面时)。
- 避免同时为许多元素的大量属性添加动画;必要时简化动画或按顺序执行。
最佳实践
- ✅ 为 transform 和 opacity 添加动画;仅对会添加动画的元素使用 CSS will-change。
- ✅ 当动画相同时,使用 stagger 代替多个带手动延迟的独立补间动画。
- ✅ 对频繁更新的属性(例如鼠标跟随元素)使用 gsap.quickTo()。
- ✅ 清理或终止画面外的动画;布局变化时调用 ScrollTrigger.refresh(),并尽可能使用防抖。
请勿
- ❌ 若使用 x/y/scale 就能实现相同效果,不要通过 width/height/top/left 添加移动动画。
- ❌ 不要为了“以防万一”而在每个元素上设置 will-change 或 force3D;仅用于实际添加动画的元素。
- ❌ 未在低端设备上测试时,不要创建数百个重叠的补间动画或 ScrollTrigger。
- ❌ 不要忽略清理;残留的补间动画和 ScrollTrigger 会持续运行,影响性能和正确性。