Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Audits and fixes CSS/JS animation performance issues including layout thrashing, compositor misuse, and scroll-linked motion.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: fixing-motion-performance3description: Audit and fix animation performance issues including layout thrashing, compositor properties, scroll-linked motion, and blur effects. Use when animations stutter, transitions jank, or reviewing CSS/JS animation performance.4---56# fixing-motion-performance78Fix animation performance issues.910## how to use1112- `/fixing-motion-performance`13Apply these constraints to any UI animation work in this conversation.1415- `/fixing-motion-performance <file>`16Review the file against all rules below and report:17- violations (quote the exact line or snippet)18- why it matters (one short sentence)19- a concrete fix (code-level suggestion)2021Do not migrate animation libraries unless explicitly requested. Apply rules within the existing stack.2223## when to apply2425Reference these guidelines when:26- adding or changing UI animations (CSS, WAAPI, Motion, rAF, GSAP)27- refactoring janky interactions or transitions28- implementing scroll-linked motion or reveal-on-scroll29- animating layout, filters, masks, gradients, or CSS variables30- reviewing components that use will-change, transforms, or measurement3132## rendering steps glossary3334- composite: transform, opacity35- paint: color, borders, gradients, masks, images, filters36- layout: size, position, flow, grid, flex3738## rule categories by priority3940| priority | category | impact |41|----------|----------|--------|42| 1 | never patterns | critical |43| 2 | choose the mechanism | critical |44| 3 | measurement | high |45| 4 | scroll | high |46| 5 | paint | medium-high |47| 6 | layers | medium |48| 7 | blur and filters | medium |49| 8 | view transitions | low |50| 9 | tool boundaries | critical |5152## quick reference5354### 1. never patterns (critical)5556- do not interleave layout reads and writes in the same frame57- do not animate layout continuously on large or meaningful surfaces58- do not drive animation from scrollTop, scrollY, or scroll events59- no requestAnimationFrame loops without a stop condition60- do not mix multiple animation systems that each measure or mutate layout6162### 2. choose the mechanism (critical)6364- default to transform and opacity for motion65- use JS-driven animation only when interaction requires it66- paint or layout animation is acceptable only on small, isolated surfaces67- one-shot effects are acceptable more often than continuous motion68- prefer downgrading technique over removing motion entirely6970### 3. measurement (high)7172- measure once, then animate via transform or opacity73- batch all DOM reads before writes74- do not read layout repeatedly during an animation75- prefer FLIP-style transitions for layout-like effects76- prefer approaches that batch measurement and writes7778### 4. scroll (high)7980- prefer Scroll or View Timelines for scroll-linked motion when available81- use IntersectionObserver for visibility and pausing82- do not poll scroll position for animation83- pause or stop animations when off-screen84- scroll-linked motion must not trigger continuous layout or paint on large surfaces8586### 5. paint (medium-high)8788- paint-triggering animation is allowed only on small, isolated elements89- do not animate paint-heavy properties on large containers90- do not animate CSS variables for transform, opacity, or position91- do not animate inherited CSS variables92- scope animated CSS variables locally and avoid inheritance9394### 6. layers (medium)9596- compositor motion requires layer promotion, never assume it97- use will-change temporarily and surgically98- avoid many or large promoted layers99- validate layer behavior with tooling when performance matters100101### 7. blur and filters (medium)102103- keep blur animation small (<=8px)104- use blur only for short, one-time effects105- never animate blur continuously106- never animate blur on large surfaces107- prefer opacity and translate before blur108109### 8. view transitions (low)110111- use view transitions only for navigation-level changes112- avoid view transitions for interaction-heavy UI113- avoid view transitions when interruption or cancellation is required114- treat size changes as potentially layout-triggering115116### 9. tool boundaries (critical)117118- do not migrate or rewrite animation libraries unless explicitly requested119- apply these rules within the existing animation system120- never partially migrate APIs or mix styles within the same component121122## common fixes123124```css125/* layout thrashing: animate transform instead of width */126/* before */ .panel { transition: width 0.3s; }127/* after */ .panel { transition: transform 0.3s; }128129/* scroll-linked: use scroll-timeline instead of JS */130/* before */ window.addEventListener('scroll', () => el.style.opacity = scrollY / 500)131/* after */ .reveal { animation: fade-in linear; animation-timeline: view(); }132```133134```js135// measurement: batch reads before writes (FLIP)136// before — layout thrash137el.style.left = el.getBoundingClientRect().left + 10 + 'px';138// after — measure once, animate via transform139const first = el.getBoundingClientRect();140el.classList.add('moved');141const last = el.getBoundingClientRect();142el.style.transform = `translateX(${first.left - last.left}px)`;143requestAnimationFrame(() => { el.style.transition = 'transform 0.3s'; el.style.transform = ''; });144```145146## review guidance147148- enforce critical rules first (never patterns, tool boundaries)149- choose the least expensive rendering work that matches the intent150- for any non-default choice, state the constraint that justifies it (surface size, duration, or interaction requirement)151- when reviewing, prefer actionable notes and concrete alternatives over theory152