Super smooth animations

Expectation

Reality

Battery drain

Device overheating

Maillard

Giacomo Zinetti

@gcmznt

How browser renders?

Render cycle

JavaScript

Style

Layout

Paint

Composite

Our logic

JavaScript

Style

Layout

Paint

Composite

margin
padding

 

Reflow

JavaScript

Style

Layout

Paint

Composite

color
background

 

Repaint

JavaScript

Style

Layout

Paint

Composite

transform
opacity

 

Compose

JavaScript

Style

Layout

Paint

Composite

CSS

Animate compositor-only properties

Left
Translate

Create layers

will-change

* {
  will-change: transform;
}

Disable hover on scroll

JS

Avoid forced synchronous layout

elements.forEach(el => {
  el.querySelector('img').style.width
    = `${el.offsetWidth}px`;
})

🤓

elements.forEach((el, i) => {
  ws[i] = el.offsetWidth;
})
elements.forEach((el, i) => {
  el.querySelector('img').style.width
    = `${ws[i]}px`;
})

rAF

requestAnimationFrame()

rIC

requestIdleCallback()

Split big tasks

Web workers

TARGET
RAIL

Response <100ms
Animation <16ms
Idle      <50ms
Load    <1000ms

FLIP

by @aerotwist

First

const first =
  el.getBoundingClientRect();

Last

el.classList.toggle('end');
const last =
  el.getBoundingClientRect();

Invert

const invert =
  first.height / last.height;

Play

el.animate([
  { transform: `scaleY(${invert})` },
  { transform: 'scaleY(1)' }
], 300);

First 
Last  
Invert
Play   

Content
VS
Animations

Users!

The best animation is the invisible one

Thank you 🙏

Links