ESC
Type to search guides, tutorials, and reference documentation.
Verified by Garnet Grid

Web Animation Performance

Build smooth 60fps animations that don't jank. Covers CSS animations vs. JavaScript, compositor-only properties, requestAnimationFrame, FLIP technique, and the patterns that keep animations fluid on every device.

Smooth animations run at 60 frames per second — which means each frame has just 16.6 milliseconds to render. Triggering layout recalculation or paint inside an animation frame will cause jank — visible stuttering that destroys the perception of quality. The key is understanding which CSS properties are cheap and which are expensive.


The Rendering Pipeline

Browser Rendering Pipeline:

JavaScript → Style → Layout → Paint → Composite

Ideal animation: Skip layout and paint entirely
  transform: translateX(100px)  ✓ Compositor only
  opacity: 0.5                  ✓ Compositor only
  
Expensive animation: Triggers layout + paint
  width: 200px                  ✗ Triggers layout
  height: 200px                 ✗ Triggers layout
  top: 50px                     ✗ Triggers layout
  left: 100px                   ✗ Triggers layout
  margin: 10px                  ✗ Triggers layout
  
Medium cost: Triggers paint only
  background-color: red         ~ Triggers paint (no layout)
  box-shadow: ...               ~ Triggers paint
  border-radius: ...            ~ Triggers paint

Rule: Only animate transform and opacity for smooth performance
  Move:  transform: translate(x, y)     not  left/top
  Scale: transform: scale(x)            not  width/height
  Fade:  opacity: 0                     not  visibility
  Rotate: transform: rotate(45deg)      always use transform

FLIP Technique

// FLIP: First, Last, Invert, Play
// Animate layout changes at 60fps without layout thrashing

function flipAnimate(element, callback) {
  // FIRST: Record starting position
  const first = element.getBoundingClientRect();
  
  // Trigger the DOM change (e.g., reorder list items)
  callback();
  
  // LAST: Record ending position
  const last = element.getBoundingClientRect();
  
  // INVERT: Calculate the difference and apply inverse transform
  const deltaX = first.left - last.left;
  const deltaY = first.top - last.top;
  const deltaW = first.width / last.width;
  const deltaH = first.height / last.height;
  
  element.style.transform = `translate(${deltaX}px, ${deltaY}px) scale(${deltaW}, ${deltaH})`;
  element.style.transformOrigin = 'top left';
  
  // Force browser to acknowledge the inverted position
  element.getBoundingClientRect(); // Force reflow
  
  // PLAY: Animate to identity transform (the actual new position)
  element.style.transition = 'transform 300ms ease-out';
  element.style.transform = '';
  
  element.addEventListener('transitionend', () => {
    element.style.transition = '';
    element.style.transformOrigin = '';
  }, { once: true });
}

// Usage:
// flipAnimate(listItem, () => {
//   list.insertBefore(listItem, list.firstChild); // Move to top
// });

Anti-Patterns

Anti-PatternConsequenceFix
Animate width/height/top/leftTriggers layout every frame, jankUse transform: translate/scale instead
JavaScript animation with setIntervalInconsistent timing, missed framesUse requestAnimationFrame or CSS transitions
Animate too many elementsGPU memory overflow, stutterLimit animated elements, use will-change sparingly
will-change on everythingGPU memory waste, opposite of intendedOnly on elements about to animate, remove after
No reduced-motion supportAccessibility violation, motion sickness@media (prefers-reduced-motion: reduce)

Animation performance is about doing less work per frame. Use compositor-only properties (transform, opacity), avoid layout thrashing, and respect user motion preferences. A smooth 60fps animation at half the visual complexity beats a complex animation that stutters.

Jakub Dimitri Rezayev
Jakub Dimitri Rezayev
Founder & Chief Architect • Garnet Grid Consulting

Jakub holds an M.S. in Customer Intelligence & Analytics and a B.S. in Finance & Computer Science from Pace University. With deep expertise spanning D365 F&O, Azure, Power BI, and AI/ML systems, he architects enterprise solutions that bridge legacy systems and modern technology — and has led multi-million dollar ERP implementations for Fortune 500 supply chains.

View Full Profile →