Shots in this scene
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.
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
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 transformand, once the 300 ms transition ends,finished: will-change auto. - 2
Remove will-change from the blurry word
In "Blurry text on a scaled layer" delete the
.keptrule'swill-change: transform;line and run it again. Both words are crisp after 300 ms.
Code & diagrams
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.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
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 MBNothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
Console
Nothing logged yet.Expected console output
at rest: will-change auto
on click: will-change transform
moving: will-change transform
finished: will-change autoThe left word's `will-change: transform` fixes its picture at 1× size, so it looks soft at 3×.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
Console
Nothing logged yet.Expected console output
left: transform | right: autoBreak 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.
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
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-changelets you ask earlier, and much advice says to put it on everything. Know what you pay for it. - 2
What makes a layer. Chromium gives an element its own layer for several reasons: a running
transformoropacityanimation, a 3D transform,<video>and<canvas>, andwill-change: transformoropacity. 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
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
**Use
will-changein a window.** Set it shortly before the change, for example onpointerenteror in the click handler, wait a frame, start the change, and remove it when the animation ends (transitionend,animationendor thefinishedpromise). A permanentwill-changeis fine for one or two elements that are always moving (a drawer, the hero). - 5
Blurry text. A layer made with
will-change: transformis 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. Removewill-changewhen the animation ends, or do not scale text up from small.
Explain it without notes
What does a layer cost, and how do you work it out?
How should will-change be used, and why not put it in the stylesheet everywhere?
Practice
A gallery has 80 thumbnails that scale up on hover. Write the CSS and JS so only the hovered one has a layer.
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-changein a window and remove it afterwardsYou know why 500
will-changeelements are a problemYou can say why scaled text can turn blurry on a promoted layer