GSAP 效能
何時使用此技能
在最佳化 GSAP 動畫以達到流暢 60fps、減少佈局/繪製成本,或使用者詢問效能、卡頓及快速動畫最佳實務時,請套用此技能。
相關技能: 使用 gsap-core(transform、autoAlpha)和 gsap-timeline 建立動畫;ScrollTrigger 效能相關請參閱 gsap-scrolltrigger。
偏好 Transform 與 Opacity
動畫 transform(x、y、scaleX、scaleY、rotation、rotationX、rotationY、skewX、skewY)和 opacity 可將工作保留在複合器層級,避免佈局與大多數繪製。當 transform 能達到相同效果時,請避免動畫佈局密集屬性。
- ✅ 優先使用:x、y、scale、rotation、opacity。
- ❌ 盡量避免:width、height、top、left、margin、padding(它們會觸發佈局並可能導致卡頓)。
GSAP 的 x 和 y 預設使用 transform(translate);請用它們取代 left/top 來移動。
will-change
在 CSS 中對即將動畫的元素使用 will-change,可提示瀏覽器提升圖層。
will-change: transform;
批次讀取與寫入
GSAP 內部會批次處理更新。當 GSAP 與直接 DOM 讀取/寫入或依賴佈局的程式碼混合使用時,請避免交錯讀取與寫入而造成反覆的佈局抖動。優先完成所有讀取,再進行所有寫入(或讓 GSAP 一次處理所有寫入)。
大量元素(Stagger、清單)
- 當動畫相同時,使用 stagger 而非多個帶手動延遲的獨立 tween,這更有效率。
- 對於長清單,考慮 虛擬化 或僅動畫可見項目;避免建立數百個同時進行的 tween(若會導致卡頓)。
- 盡可能重用時間軸;避免每影格建立新時間軸。
頻繁更新的屬性(例如滑鼠跟隨器)
對於經常更新的屬性(例如滑鼠跟隨器的 x/y),優先使用 gsap.quickTo() 。它會重用單一 tween,而非每次更新都建立新 tween。
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 而非多個帶手動延遲的獨立 tween。
- ✅ 對頻繁更新的屬性(例如滑鼠跟隨器)使用 gsap.quickTo() 。
- ✅ 清理或終止離螢幕動畫;當佈局變更時,以去抖方式呼叫 ScrollTrigger.refresh() 。
禁止事項
- ❌ 當 x/y/scale 能達到相同效果時,不要為了移動而動畫 width/height/top/left。
- ❌ 不要「以防萬一」對每個元素設定 will-change 或 force3D;僅用於實際動畫的元素。
- ❌ 不要未經低階裝置測試就建立數百個重疊的 tween 或 ScrollTrigger。
- ❌ 不要忽略清理;殘留的 tween 和 ScrollTrigger 會持續執行並損害效能與正確性。