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
- Parser producing a rule list for
div {},.foo {},#header {},.parent .child {}. - Selector matching, right-to-left from the key selector.
- Specificity, cascade, inheritance, computed style.
- Naive invalidation. On any DOM change, recompute every element's style. Measure on a 10,000-node tree.
- Bucket by key selector. Measure again.
- Invalidation sets. Precompute class → affected-descendant descriptors; on
classList.add(x), consult the map. Measure again. - 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