Step 2 — How Far Does One Change Travel?

Goal

Measure invalidation scope, and understand containment as a promise you make to the engine.

Predict first

500 cards. Sixty times, we insert a row into card #10, force layout, and remove it. Three variants: no containment, contain: layout, contain: strict + fixed height.

Layout is forced synchronously every time, so the layout count is identical in all three. Predict the layout time for each.

Run

npm run invalidation

Expected output:

  variant                        | style recalc | layout    | layout count
  no containment                 |     0.5ms    |    12.7ms |          120
  contain: layout                |     0.5ms    |    10.5ms |          120
  contain: strict + fixed height |     1.5ms    |     2.5ms |          120

What just happened

Same mutation, same DOM, same 120 forced layouts. Only the permitted propagation differed.

contain: layout alone gave 18% — because the card can still change size, so following siblings may still move. The containment promise was partial.

Adding contain: size (via strict) plus a fixed height gave 80% — the box cannot resize, so nothing outside it can be affected, and layout collapses to the card's own subtree.

Note the style-recalc increase: 0.5 → 1.5 ms. Containment is not free; it adds bookkeeping. It paid 5× here and would not pay on a small subtree. You should be able to say when it would not.

The promise is also a constraint

contain: size means the box's size does not depend on its contents. If content must grow, it is clipped or collapses to zero. The optimisation and the correctness constraint are the same declaration, which is why containment belongs in code review rather than a stylesheet-wide sweep.

Why the experiment forces layout deliberately

Calling document.body.offsetHeight after every mutation is the fe-01 sin, committed on purpose: it pins layout count so the comparison measures layout cost. Without it the browser coalesces differently per variant and the numbers are not comparable.

General rule: when comparing cost, hold the count fixed. When comparing strategies, measure both.

Checkpoint

docs/verification.md Checkpoint 3.