Fixing Motion Performance
Julien Thibeaut (ibelick)CommunityCreated by Julien Thibeaut (ibelick)
- Skill
- Review and audit
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured framework for auditing and fixing animation performance issues in web interfaces. It focuses on identifying and resolving common bottlenecks such as layout thrashing, inefficient compositor usage, and expensive paint operations. By applying these guidelines, developers can ensure smooth transitions and interactions without needing to migrate existing animation libraries or frameworks.
What it does
- Audits CSS and JavaScript animations for performance bottlenecks.
- Identifies layout thrashing caused by interleaved DOM reads and writes.
- Provides concrete code-level fixes for common animation performance issues.
- Enforces best practices for scroll-linked animations and filter effects.
- Guides the optimization of compositor properties and layer promotion.
- Ensures animation consistency while respecting existing project constraints.
When to use it
- When UI animations exhibit stuttering or jank.
- During the code review of components involving complex transitions.
- When implementing scroll-linked motion or reveal-on-scroll effects.
- When refactoring animations that involve layout, filters, or CSS variables.
- When optimizing components that use will-change or transform properties.
Advantages
- Reduces visual jank by prioritizing compositor-friendly properties.
- Provides actionable, specific feedback rather than generic advice.
- Maintains project integrity by working within the existing animation stack.
- Helps developers avoid common pitfalls like layout thrashing.
- Offers clear, prioritized rules for high-impact performance improvements.
Usage examples
- “/fixing-motion-performance”
- The agent adopts the performance constraints, applying them to all subsequent UI animation tasks and code reviews in the session.
- “/fixing-motion-performance src/components/Sidebar.js”
- The agent audits the specified file, identifies performance violations like layout thrashing, explains the impact, and provides a refactored code snippet.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/ibelick/fixing-motion-performance/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip fixing-motion-performance.zip -d .agents/skills
Documentation by Julien Thibeaut (ibelick)
fixing-motion-performance
Fix animation performance issues.
how to use
/fixing-motion-performanceApply these constraints to any UI animation work in this conversation./fixing-motion-performance <file>Review the file against all rules below and report:violations (quote the exact line or snippet)
why it matters (one short sentence)
a concrete fix (code-level suggestion)
Do not migrate animation libraries unless explicitly requested. Apply rules within the existing stack.
when to apply
Reference these guidelines when:
adding or changing UI animations (CSS, WAAPI, Motion, rAF, GSAP)
refactoring janky interactions or transitions
implementing scroll-linked motion or reveal-on-scroll
animating layout, filters, masks, gradients, or CSS variables
reviewing components that use will-change, transforms, or measurement
rendering steps glossary
composite: transform, opacity
paint: color, borders, gradients, masks, images, filters
layout: size, position, flow, grid, flex
rule categories by priority
| priority | category | impact |
|---|---|---|
| 1 | never patterns | critical |
| 2 | choose the mechanism | critical |
| 3 | measurement | high |
| 4 | scroll | high |
| 5 | paint | medium-high |
| 6 | layers | medium |
| 7 | blur and filters | medium |
| 8 | view transitions | low |
| 9 | tool boundaries | critical |
quick reference
1. never patterns (critical)
do not interleave layout reads and writes in the same frame
do not animate layout continuously on large or meaningful surfaces
do not drive animation from scrollTop, scrollY, or scroll events
no requestAnimationFrame loops without a stop condition
do not mix multiple animation systems that each measure or mutate layout
2. choose the mechanism (critical)
default to transform and opacity for motion
use JS-driven animation only when interaction requires it
paint or layout animation is acceptable only on small, isolated surfaces
one-shot effects are acceptable more often than continuous motion
prefer downgrading technique over removing motion entirely
3. measurement (high)
measure once, then animate via transform or opacity
batch all DOM reads before writes
do not read layout repeatedly during an animation
prefer FLIP-style transitions for layout-like effects
prefer approaches that batch measurement and writes
4. scroll (high)
prefer Scroll or View Timelines for scroll-linked motion when available
use IntersectionObserver for visibility and pausing
do not poll scroll position for animation
pause or stop animations when off-screen
scroll-linked motion must not trigger continuous layout or paint on large surfaces
5. paint (medium-high)
paint-triggering animation is allowed only on small, isolated elements
do not animate paint-heavy properties on large containers
do not animate CSS variables for transform, opacity, or position
do not animate inherited CSS variables
scope animated CSS variables locally and avoid inheritance
6. layers (medium)
compositor motion requires layer promotion, never assume it
use will-change temporarily and surgically
avoid many or large promoted layers
validate layer behavior with tooling when performance matters
7. blur and filters (medium)
keep blur animation small (<=8px)
use blur only for short, one-time effects
never animate blur continuously
never animate blur on large surfaces
prefer opacity and translate before blur
8. view transitions (low)
use view transitions only for navigation-level changes
avoid view transitions for interaction-heavy UI
avoid view transitions when interruption or cancellation is required
treat size changes as potentially layout-triggering
9. tool boundaries (critical)
do not migrate or rewrite animation libraries unless explicitly requested
apply these rules within the existing animation system
never partially migrate APIs or mix styles within the same component
common fixes
/* layout thrashing: animate transform instead of width */
/* before */ .panel { transition: width 0.3s; }
/* after */ .panel { transition: transform 0.3s; }
/* scroll-linked: use scroll-timeline instead of JS */
/* before */ window.addEventListener('scroll', () => el.style.opacity = scrollY / 500)
/* after */ .reveal { animation: fade-in linear; animation-timeline: view(); }// measurement: batch reads before writes (FLIP)
// before — layout thrash
el.style.left = el.getBoundingClientRect().left + 10 + 'px';
// after — measure once, animate via transform
const first = el.getBoundingClientRect();
el.classList.add('moved');
const last = el.getBoundingClientRect();
el.style.transform = `translateX(${first.left - last.left}px)`;
requestAnimationFrame(() => { el.style.transition = 'transform 0.3s'; el.style.transform = ''; });review guidance
enforce critical rules first (never patterns, tool boundaries)
choose the least expensive rendering work that matches the intent
for any non-default choice, state the constraint that justifies it (surface size, duration, or interaction requirement)
when reviewing, prefer actionable notes and concrete alternatives over theory
Files
- ATTRIBUTION.mdAdded by AutoGineer901 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md5.4 KiB
SKILL.md
fixing-motion-performance
Fix animation performance issues.
how to use
/fixing-motion-performanceApply these constraints to any UI animation work in this conversation./fixing-motion-performance <file>Review the file against all rules below and report:violations (quote the exact line or snippet)
why it matters (one short sentence)
a concrete fix (code-level suggestion)
Do not migrate animation libraries unless explicitly requested. Apply rules within the existing stack.
when to apply
Reference these guidelines when:
adding or changing UI animations (CSS, WAAPI, Motion, rAF, GSAP)
refactoring janky interactions or transitions
implementing scroll-linked motion or reveal-on-scroll
animating layout, filters, masks, gradients, or CSS variables
reviewing components that use will-change, transforms, or measurement
rendering steps glossary
composite: transform, opacity
paint: color, borders, gradients, masks, images, filters
layout: size, position, flow, grid, flex
rule categories by priority
| priority | category | impact |
|---|---|---|
| 1 | never patterns | critical |
| 2 | choose the mechanism | critical |
| 3 | measurement | high |
| 4 | scroll | high |
| 5 | paint | medium-high |
| 6 | layers | medium |
| 7 | blur and filters | medium |
| 8 | view transitions | low |
| 9 | tool boundaries | critical |
quick reference
1. never patterns (critical)
do not interleave layout reads and writes in the same frame
do not animate layout continuously on large or meaningful surfaces
do not drive animation from scrollTop, scrollY, or scroll events
no requestAnimationFrame loops without a stop condition
do not mix multiple animation systems that each measure or mutate layout
2. choose the mechanism (critical)
default to transform and opacity for motion
use JS-driven animation only when interaction requires it
paint or layout animation is acceptable only on small, isolated surfaces
one-shot effects are acceptable more often than continuous motion
prefer downgrading technique over removing motion entirely
3. measurement (high)
measure once, then animate via transform or opacity
batch all DOM reads before writes
do not read layout repeatedly during an animation
prefer FLIP-style transitions for layout-like effects
prefer approaches that batch measurement and writes
4. scroll (high)
prefer Scroll or View Timelines for scroll-linked motion when available
use IntersectionObserver for visibility and pausing
do not poll scroll position for animation
pause or stop animations when off-screen
scroll-linked motion must not trigger continuous layout or paint on large surfaces
5. paint (medium-high)
paint-triggering animation is allowed only on small, isolated elements
do not animate paint-heavy properties on large containers
do not animate CSS variables for transform, opacity, or position
do not animate inherited CSS variables
scope animated CSS variables locally and avoid inheritance
6. layers (medium)
compositor motion requires layer promotion, never assume it
use will-change temporarily and surgically
avoid many or large promoted layers
validate layer behavior with tooling when performance matters
7. blur and filters (medium)
keep blur animation small (<=8px)
use blur only for short, one-time effects
never animate blur continuously
never animate blur on large surfaces
prefer opacity and translate before blur
8. view transitions (low)
use view transitions only for navigation-level changes
avoid view transitions for interaction-heavy UI
avoid view transitions when interruption or cancellation is required
treat size changes as potentially layout-triggering
9. tool boundaries (critical)
do not migrate or rewrite animation libraries unless explicitly requested
apply these rules within the existing animation system
never partially migrate APIs or mix styles within the same component
common fixes
/* layout thrashing: animate transform instead of width */
/* before */ .panel { transition: width 0.3s; }
/* after */ .panel { transition: transform 0.3s; }
/* scroll-linked: use scroll-timeline instead of JS */
/* before */ window.addEventListener('scroll', () => el.style.opacity = scrollY / 500)
/* after */ .reveal { animation: fade-in linear; animation-timeline: view(); }// measurement: batch reads before writes (FLIP)
// before — layout thrash
el.style.left = el.getBoundingClientRect().left + 10 + 'px';
// after — measure once, animate via transform
const first = el.getBoundingClientRect();
el.classList.add('moved');
const last = el.getBoundingClientRect();
el.style.transform = `translateX(${first.left - last.left}px)`;
requestAnimationFrame(() => { el.style.transition = 'transform 0.3s'; el.style.transform = ''; });review guidance
enforce critical rules first (never patterns, tool boundaries)
choose the least expensive rendering work that matches the intent
for any non-default choice, state the constraint that justifies it (surface size, duration, or interaction requirement)
when reviewing, prefer actionable notes and concrete alternatives over theory
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Julien Thibeaut (ibelick)
- Publisher
- Julien Thibeaut (ibelick) (Community)
- Source
- ibelick/ui-skills · skills/fixing-motion-performance · commit 97dea9e
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Julien Thibeaut (ibelick) or Julien Thibeaut (ibelick).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download fixing-motion-performance.zip