Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 6.3Intermediate ~20 min · shot 3 of 7

Layers and will-change

In one line

A layer is a painted picture the compositor can move on its own, and every layer costs memory (width × height × 4 bytes). will-change asks for a layer early. Used on a few elements for a short time it helps; used everywhere it wastes memory and can make text blurry.

0/7 · 0%

Think of it like this

An overhead-projector slide. If you write the logo on its own clear sheet, you can slide that sheet across the picture for free, without redrawing anything. But each sheet is one more thing to store and to carry. A hundred sheets for a hundred small marks would make the projector slow, not fast.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

layer
A painted picture of part of the page that the compositor can move, fade or transform on its own.
promote
To give an element its own layer.
will-change
A CSS hint that a property is about to change, so the browser can prepare, for example by making a layer.
layer explosion
Too many layers, so memory and compositing work grow and the page gets slower.
device pixel
One physical dot on the screen. On a 3× phone screen one CSS pixel is 3 × 3 device pixels.

Step by step

01Count what a layer costs

"The cost of layers" starts with 100 boxes of 60 × 60. Press will-change on all: 100 promoted, 1.4 MB. Press 100 / 500 items and promote again: 500 boxes, 7.2 MB.

02See the edge: not promoted, not charged

Press will-change off: 0 promoted, 0.0 MB.

03Open a window around the motion

"A will-change window" sets will-change: transform in the click handler, waits two frames, lifts the card and clears it on transitionend. The console prints auto, transform, transform, auto.

04Look at blurry text

"Blurry text on a scaled layer" scales two words to 3× after the first paint. The left has will-change: transform and is soft at the edges. The right has not and is crisp.

Try it yourself

  1. 1

    Watch the window in the console

    In "A will-change window" press the card twice. After each press the console shows on click: will-change transform, moving: will-change transform and, once the 300 ms transition ends, finished: will-change auto.

  2. 2

    Remove will-change from the blurry word

    In "Blurry text on a scaled layer" delete the .kept rule's will-change: transform; line and run it again. Both words are crisp after 300 ms.

Code & diagrams

The cost of layers

Estimated as width × height × 4 bytes at 1× density, so a 3× phone needs 9 times as much. It is a formula, not a readout: Chrome's Layers panel shows real numbers.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

start: 0 of 100 promoted, 0.0 MB
on: 100 of 100 promoted, 1.4 MB
refilled: 0 of 500 promoted, 0.0 MB
on: 500 of 500 promoted, 7.2 MB
off: 0 of 500 promoted, 0.0 MB
A will-change window
Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

at rest: will-change auto
on click: will-change transform
moving: will-change transform
finished: will-change auto
Blurry text on a scaled layer

The left word's `will-change: transform` fixes its picture at 1× size, so it looks soft at 3×.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

left: transform | right: auto

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Forget to clear will-change

In "A will-change window" delete the line card.style.willChange = ""; in the transitionend handler.

terminal
$ Click the card and wait for the transition to end
── what you'll see ──
at rest: will-change auto
on click: will-change transform
moving: will-change transform
finished: will-change transform
The last line should say `auto`.

Myth vs fact

Myth

will-change: transform makes an animation faster.

Fact

It makes the layer exist earlier. The animation itself runs the same. It helps when preparing the layer is the slow part, and hurts through memory when overused.

Remember this

  1. 1

    The problem this solves: the cheap animations of Topic 6.1 work because the moving element is its own layer. The browser usually decides that when an animation starts. will-change lets you ask earlier, and much advice says to put it on everything. Know what you pay for it.

  2. 2

    What makes a layer. Chromium gives an element its own layer for several reasons: a running transform or opacity animation, a 3D transform, <video> and <canvas>, and will-change: transform or opacity. Elements drawn above a promoted element may be promoted too, to keep the stacking order right. The main thread repaints only the layer that changed.

  3. 3

    What a layer costs. A layer is a texture: width × height × 4 bytes (red, green, blue and alpha), at device pixels. A full-screen 1280 × 720 layer is 3,686,400 bytes, about 3.7 MB. On a phone with 3 device pixels per CSS pixel the same layer is 9 times larger: 33,177,600 bytes, about 33 MB. Memory on a cheap phone is limited.

  4. 4

    **Use will-change in a window.** Set it shortly before the change, for example on pointerenter or in the click handler, wait a frame, start the change, and remove it when the animation ends (transitionend, animationend or the finished promise). A permanent will-change is fine for one or two elements that are always moving (a drawer, the hero).

  5. 5

    Blurry text. A layer made with will-change: transform is drawn once, at the scale it has when it is first painted. Scale it up later and the browser stretches that picture instead of drawing the text again. Remove will-change when the animation ends, or do not scale text up from small.

Explain it without notes

01

What does a layer cost, and how do you work it out?

02

How should will-change be used, and why not put it in the stylesheet everywhere?

Practice

01

A gallery has 80 thumbnails that scale up on hover. Write the CSS and JS so only the hovered one has a layer.

02

A 390 × 844 CSS-pixel full-screen overlay is its own layer on a phone with density 3. Work out its memory.

Done when you can

  • You can work out a layer's memory from its size and the screen density

  • You can set will-change in a window and remove it afterwards

  • You know why 500 will-change elements are a problem

  • You can say why scaled text can turn blurry on a promoted layer