we (web engine): Experimental web browser project to understand the limits of Claude

Style sharing cache #141

open opened by pierrelf.com

Summary#

Implement a style sharing cache that reuses computed styles across elements with identical styling inputs, avoiding redundant cascade resolution.

Background#

Currently, resolve_styles() in crates/style/src/computed.rs runs the full cascade (collect matching rules → sort by specificity → apply declarations) for every element on every render. Many elements on a typical page share identical styles (e.g., list items, table cells, paragraphs). A style sharing cache detects these cases and reuses the computed style.

Acceptance Criteria#

  • Define a style cache key based on the inputs that determine computed style:
    • Set of matching rule indices (or a hash of matched selectors + specificity)
    • Inline style attribute (if any)
    • Inherited style from parent (pointer equality or hash)
    • Element's tag name and namespace
  • StyleCache struct: maps cache keys to Arc<ComputedStyle> (or Rc<ComputedStyle>)
  • During resolve_styles(), before running the cascade for an element:
    1. Compute the cache key
    2. Check the cache — if hit, clone the Arc and skip cascade resolution
    3. If miss, run the cascade, store result in cache, return
  • Cache is scoped per style resolution pass (cleared between renders, or use generation counters)
  • Sharing works for inherited properties: if parent style is shared, children can share too
  • All existing style/layout/render tests pass
  • Add tests verifying cache hit rates on documents with repeated structures (e.g., <ul> with many <li> elements)

Implementation Notes#

  • The key insight: two elements with the same matched rules, same inline styles, and same inherited parent will always produce the same computed style
  • Hashing the matched rule set is efficient — rules already carry specificity and source order
  • Arc<ComputedStyle> enables zero-cost sharing; clone is just a refcount bump
  • Custom properties (var()) complicate sharing — elements with different custom property environments can't share even if rules match. Include custom property state in the cache key.
  • Start simple: cache on (matched_rules_hash, inline_style_hash, parent_style_ptr). Refine if needed.

Dependencies#

None — independent of JS/layout work.

Phase#

Phase 15: Performance

sign up or login to add to the discussion
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:meotu43t6usg4qdwzenk4s2t/sh.tangled.repo.issue/3mi4zznbvx327