What the declaration asks for
will-change tells the browser to prepare for a change to the named property. For transform, preparing in practice means giving the element its own compositor layer now, so that a later transform can be applied to finished pixels without repainting. The neighbouring page on why transform is cheaper than top covers that mechanism. This question is about what happens when the hint is applied to everything.
The answer is that the browser mostly does what it was asked. A list of two hundred cards becomes two hundred compositor layers, each with its own backing raster, whether or not any card ever moves.
Putting a number on the memory
A layer's raster is sized in device pixels, not CSS pixels, and the device pixel ratio multiplies both dimensions. Take a card of 360 by 200 CSS pixels on a phone with a ratio of 3. That is 1080 by 600 device pixels. At four bytes per pixel for an uncompressed RGBA raster, one card is about 2.6 MB.
Two hundred such cards would ask for over 500 MB. Browsers do not necessarily rasterise every layer in full, and they tile and skip content far from the viewport, so treat this as the scale of what was requested rather than a measurement. Still, a desktop with a large GPU memory budget absorbs it, and a mid-range phone does not. When the budget runs out, the visible symptoms are blank or checkerboarded regions during fast scrolls, rasterisation falling behind, and on memory-constrained devices the tab being discarded in the background.
Compositor layers cost time as well as memory
Memory is the headline cost, but not the only one. Every layer has to be rasterised at least once, and the browser has to maintain the layer tree on the main thread: decide what is promoted, test which layers overlap, and send updates to the compositor. More compositor layers means more of that bookkeeping on every change, and more quads for the compositor to draw each frame. None of that work existed before the rule went in.
The promotion also changes layout semantics, which is easy to miss in a performance review. will-change: transform creates a stacking context, so a dropdown inside a card can no longer escape above the next card through z-index. It also makes the card the containing block for fixed-position descendants, the same failure described in the fixed header that started scrolling away. A blanket rule can ship visual bugs alongside the slowdown.
Modern browsers scroll on the compositor where they can. The scrolling content is already handled as a composited surface, so the cards inside it move with the scroll whether or not each one has its own layer. Promoting each card added nothing to the scroll itself.
Scroll jank usually has a main-thread cause. A touchstart or wheel listener that is not passive makes the compositor wait for JavaScript before it can scroll. A scroll handler that reads geometry and writes styles forces layout on every event. Large areas that repaint during the scroll, such as a fixed background or a box shadow that changes, keep the raster threads busy. Images decoding as they come into view can also stall frames. The original complaint was real; the diagnosis behind the fix was not.
Reading the layers instead of the stylesheet
The way to settle this is to look at what the browser built. In Chrome DevTools, the Layers panel lists every compositor layer with a memory estimate and the reason it was promoted, and the Rendering drawer can draw layer borders over the live page. Count the layers with the rule, remove it, and count again. Then record a performance trace of the scroll on the device itself, connected by remote debugging, and look for long tasks, forced layouts and large paint events.
Testing on the device is not optional here. DevTools CPU throttling slows script and layout, but it does not shrink your laptop's GPU memory. A layer explosion that is harmless on a desktop can only be reproduced on hardware with a phone's limits.
Mistaking a hint for a speed-up
The adequate answer says "too many layers use memory" and stops. The strong answer explains that will-change reserves resources rather than making anything faster, that browsers already promote an element while a transform or opacity animation is running on it, and that the hint mostly buys back the first frame of an animation. Applied to every card, it buys that frame two hundred times for animations that may never run.
The repair is narrow. Delete the blanket rule. If a card genuinely animates on interaction, add the hint shortly before the animation and remove it when it finishes.
card.addEventListener('pointerenter', () => {
card.style.willChange = 'transform';
});
card.addEventListener('transitionend', () => {
card.style.willChange = 'auto';
});
Then fix the scroll jank at its cause, which the trace will name.
will-change is a reservation of memory and compositing work, not a performance switch. Put it on the element about to move, for as long as it moves, and look for scroll jank on the main thread.
© 2026 Preptima. Originally published at preptima.com (opens in a new tab).