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

Memory profiling and optimization pass #146

open opened by pierrelf.com

Summary#

Profile memory usage across all subsystems and optimize the most impactful allocations. This is the final issue in Phase 15, meant to be tackled after other optimizations are in place.

Background#

A browser engine allocates heavily: DOM nodes, layout boxes, style data, JS heap objects, display lists, glyph atlases, connection buffers. This issue is about measuring where memory goes and reducing waste through targeted optimizations.

Acceptance Criteria#

  • Memory accounting: add lightweight allocation tracking to major subsystems:
    • DOM tree (node count, estimated bytes)
    • Layout tree (box count, estimated bytes)
    • Style data (computed style count, cache stats)
    • JS heap (GC live count, total allocated, collection stats)
    • Glyph atlas (pages allocated, utilization percentage)
    • Network buffers (connection pool size, TLS session cache)
    • Display list (command count, estimated bytes)
  • Debug stats command: expose memory stats via a debug interface (e.g., about:memory page or console command)
  • Optimization: String interning for DOM tag names, attribute names, CSS property names — these repeat heavily
  • Optimization: Small-string optimization for short strings (e.g., class names, IDs) — inline up to 23 bytes
  • Optimization: Arena allocation for layout boxes — allocate from a bump arena per layout pass, free all at once
  • Optimization: ComputedStyle size reduction — audit the ~120-field struct, use bitflags for boolean properties, pack enums tightly
  • Optimization: Display list compaction — reuse display list buffer between frames (clear + refill instead of drop + alloc)
  • GC tuning: adjust collection thresholds based on profiling data; consider generational hints
  • Document findings: which subsystems use the most memory, what optimizations had the biggest impact

Implementation Notes#

  • Start by adding fn memory_usage(&self) -> usize methods to key structures
  • Use std::mem::size_of and manual counting for heap allocations
  • String interning: a global HashMap<String, InternedId> with InternedId = u32 — store IDs instead of strings
  • Arena allocator: simple bump allocator (Vec<u8> with a pointer) — no need for a full allocator crate
  • For ComputedStyle: many CSS properties have a small number of variants — use u8 enums and bitfields
  • Profile on real pages (load a few popular sites) to find actual bottlenecks vs. theoretical ones
  • All optimizations must maintain correctness — run full test suite after each change

Dependencies#

  • Should be done after: all other Phase 15 issues (benefits from seeing the full picture)

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/3mi524hd5c52g