bi-07 step 02 — mini-browser M4–M6: naive first, then index

Goal

Build a CSS engine, measure it while it is naive, and only then optimise — so the cost curve is something you produced rather than were told.

Tasks

  1. Parser producing a rule list for div {}, .foo {}, #header {}, .parent .child {}.
  2. Selector matching, right-to-left from the key selector.
  3. Specificity, cascade, inheritance, computed style.
  4. Naive invalidation. On any DOM change, recompute every element's style. Measure on a 10,000-node tree.
  5. Bucket by key selector. Measure again.
  6. Invalidation sets. Precompute class → affected-descendant descriptors; on classList.add(x), consult the map. Measure again.
  7. The cliff. Add a sibling-combinator selector your analysis cannot handle precisely. Implement the subtree fallback and measure the cliff.

Done when

  • Recalculated-element counts and wall time for stages 4, 5, 6, 7
  • The selector shapes that cost you precision are named explicitly
  • You can explain where each speedup came from, not just that it happened