Shots in this scene
Interview: Rendering and Performance
In one line
Interviewers ask why transform is cheap, what layout thrashing is and how you would find jank. A strong answer gives the mechanism, a number you measured, an edge case and a trade-off. Here are six model answers checked against this course.
Think of it like this
A driving examiner does not want you to recite the highway code. She asks "why did you check the mirror there?" and listens for a reason. "Transform is faster" is a rule; the follow-up "why, and when is it not?" is where answers fall apart.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- forced layout
- The browser must lay the page out in the middle of your script, because you asked for a size right after a change that dirtied the layout.
- compositor
- The browser part that stacks painted layers and moves, fades or transforms them without the main thread.
- long animation frame (LoAF)
- A frame over 50 ms. Each entry says which scripts ran and how long they forced layout.
- INP
- Interaction to Next Paint: how long a click or key press takes to show its result. 200 ms or less is good, over 500 ms is poor.
Step by step
01Run the counter
Run "Count the forced layouts". Six lines print: three list sizes, each done two ways. Thrash reads a row's height and writes the new height, row by row. Batch reads every height, then writes every height.
02Read the sizes
With 0 rows nothing happens. With 1 row there is one read and nothing to force. With 40 rows thrash forces 39 layouts and batch forces none: the first read is free, each later read finds a waiting write.
03Say how it counts
Setting style.height queues a mutation record. The patched offsetHeight getter asks takeRecords(): a non-empty answer means a write is waiting, so the browser must lay out now.
04Say what it cannot see
It only watches offsetHeight. Reading getBoundingClientRect() or scrollTop thrashes just as badly and the counter says 0. Naming a tool's limits is part of a good answer.
Try it yourself
- 1
Make it 200 rows
Change
[0, 1, 40]to[200]. It prints200 rows, thrash: 200 reads, 199 forced layoutsand200 rows, batch: 200 reads, 0 forced layouts.
Code & diagrams
Nothing moves, so the timeline is empty on purpose: this is about layout. The counter patches `offsetHeight` and asks a mutation observer whether a style write is waiting.
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
0 rows, thrash: 0 reads, 0 forced layouts
0 rows, batch: 0 reads, 0 forced layouts
1 rows, thrash: 1 reads, 0 forced layouts
1 rows, batch: 1 reads, 0 forced layouts
40 rows, thrash: 40 reads, 39 forced layouts
40 rows, batch: 40 reads, 0 forced layoutsBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Read with getBoundingClientRect instead
In thrash, replace row.offsetHeight + 2 with row.getBoundingClientRect().height + 2.
Myth vs fact
Myth
Animating transform is always cheap.
Fact
It is cheap when CSS or the Web Animations API hands it to the compositor. A requestAnimationFrame loop that sets style.transform runs on the main thread, and a long task freezes it.
Remember this
- 1
The problem this solves: most candidates know the slogans ("animate transform and opacity"). Few can say what the browser does, give a number, or name the case where the slogan is wrong. Interviewers keep asking until they find that edge.
- 2
The shape of a good answer. Four moves, about a minute: claim (one sentence), mechanism (what the browser really does), evidence (a number you measured or a tool you would use), then edge and trade-off. Every number below comes from a run in this course (Topics 1.4 and 6.1 to 6.6).
- 3
Say what you measured, and where. Topic 6.2's table was recorded in Chromium 153, headless, with software rendering:
transform,opacity,background-color,clip-pathandbackdrop-filteronly composite;color,box-shadow,border-radiusandfilteralso paint;width,height,top,marginandfont-sizealso lay out. "In my measurements, and I would re-measure on a phone" separates you from slogan answers. - 4
Count, do not time. Timings differ on every machine; a count does not. The example below counts layout reads that arrive while a style write is waiting: 40 rows give 39 forced layouts when you alternate and 0 when you batch.
- 5
Know who drives the animation. A
transformanimation in CSS or the Web Animations API can run on the compositor, so a busy main thread does not stop it. The sametransformset from arequestAnimationFrameloop is main-thread work every frame. The property does not decide it.
Explain it without notes
What is the difference between a repaint and a reflow, and which properties cause each?
Why is transform cheap, and when is it not?
What is layout thrashing, how do you find it and how do you fix it?
requestAnimationFrame or setTimeout for an animation loop?
What do LoAF and INP measure?
An animation is smooth on your laptop and janky on a cheap phone. What do you do?
Practice
A scroll handler reads el.offsetTop and sets el.style.transform for each of 300 cards. Rewrite it.
A trace shows a 90 ms Layout block with a red triangle inside onResize. What do you check first?
Done when you can
You can answer with claim, mechanism, evidence and edge
You can say which properties composite, paint or lay out, and that you measured it
You can explain forced layout with a count, and fix it
You can say why a
requestAnimationFrametransform is not compositor-driven