- Scene
- 06
- Take
- 01
- Level
- Intermediate
- Runtime
- ~2 h
Performance
How the browser turns a change into pixels, what each property costs (measured in Chromium), layers, layout thrashing, measuring jank, and cheap phones: then fix the janky hero.
Smooth motion is a deadline: on a 60 Hz screen a new frame is due every 16.7 ms, and on a 120 Hz screen every 8.3 ms. This phase shows what the browser does inside that deadline (style, layout, paint, composite), which of those steps run on which thread, and why moving something with transform can keep going while moving it with left freezes.
You learn what each CSS property costs from Hectal's own measured table, what a layer costs in memory, why reading layout inside a loop wastes a frame, how to measure jank with DevTools and the Long Animation Frames API, and how to test for cheap phones and battery.
In the build you fix the launch page's janky hero. Its Volt drawing moves with left and its glow pulses a box-shadow. Both become cheap, and the README records the before and after numbers from a real trace.
Scene 06 · the brief from Lumen
Lena, QA at Lumen Bikes
“The hero looks lovely on Kofi's laptop. On my cheap Android phone it stutters, and it makes the whole page feel stuck.”
Kofi's first hero motion was simple: the Volt drawing drifts left and right, and a soft orange glow pulses behind it. On his laptop it is smooth. Lena opened the page on her cheap Android phone, tried to scroll while the hero moved, and the page lagged. On her 120 Hz iPhone it looked fine.
Ama asked the question every team asks: "Is it the animation or the phone?" Kofi did not know. He had never looked at what the browser does for each frame, so he did not know that his drift lays out the page 60 times a second, and that the glow paints it again each time.
In this phase you learn to look inside a frame, measure it, and fix it. By the end the hero looks the same, costs the main thread nothing, and Lena's phone scrolls smoothly under it. You also learn how to prove it with numbers instead of opinions.
In this scene
You will learn
- Name the steps of a frame and say which thread runs each one
- Read a property's cost (composite, paint or layout) and choose the cheap way to move or fade something
- Use
will-changeand layers without wasting memory, and avoid layout thrashing - Measure jank with DevTools and the Long Animation Frames API, and test for slow phones
You write code in
In your lumen-motion project (npm run dev) and in the editor on this page
Files you touch
- index.html
- src/styles/components.css
- src/js/main.js
- README.md
Shot list · 7 shots, widths by reading time
- 6.1The Rendering Pipeline in DepthA frame is style, layout, paint and composite. Some of that runs on the busy main thread and some on the compositor thread, which is why a
transformanimation can keep moving while aleftanimation freezes. 19 min 2 live - 6.2What Each Property CostsAnimating a CSS property costs one of three things each frame: only compositing, or painting again, or laying out the page and painting. Hectal measured the cost of 40 properties in Chromium, so you can choose the cheap property from data rather than from folklore. 20 min 2 live
- 6.3Layers and will-changeA layer is a painted picture the compositor can move on its own, and every layer costs memory (width × height × 4 bytes).
will-changeasks 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. 20 min 3 live - 6.4Layout ThrashingThe browser does layout once per frame, late. If your code writes a style and then reads a layout value such as
offsetHeight, the browser must do layout right now, inside your code. Repeat that in a loop and one layout becomes hundreds. The fix is to read everything first, then write everything. 19 min 2 live - 6.5Measuring Jank: DevTools and LoAFNever fix jank by guessing. DevTools' Performance panel and Rendering tab show which frames were late and why, and the Long Tasks and Long Animation Frames APIs report slow work from your own code, with the script that caused it. 19 min 1 live
- 6.6Low-End Devices, Battery and ThrottlingMost of your visitors have slower CPUs, less memory and smaller batteries than your laptop. Test with CPU throttling, pause animations nobody can see, and stop work in hidden tabs, because even a composite-only loop keeps the browser drawing every frame. 19 min 2 live
- 6.7Build: Fix the Janky HerobuildKofi's hero drifted with
leftand pulsed abox-shadow, so every frame laid out and repainted the page. You make the drift atransform, the glow an opacity pulse of a pseudo-element, pause both off screen, and write the measured before and after numbers in the README. 18 min 1 live
Dailies · 4 checked exercises
A film crew watches the day's shots every evening. Build each one yourself and press Check: the page freezes its clock and checks your motion at exact moments, its cost, and its reduced-motion version.
width, which lays out the page on every frame (red on the timeline).IntermediateD02Read first, then writegrow() makes every row 4 px taller. It reads offsetHeight and writes style.height in the same loop, so it forces a layout for each row.IntermediateD03Open a will-change windowThe card keeps will-change: transform in the stylesheet, so it holds a layer for ever. Remove it from the CSS.IntermediateD04Fix the janky hero (launch page)This is the hero as Kofi first built it: the drawing drifts with left, and the glow animates box-shadow. Make it cost nothing on the main thread, with the same look.Intermediate