Skip to content

Batch compact-stacked wrapping detection to reduce forced reflows #359

@churnish

Description

@churnish

Problem

hasWrappedPairs() performs forced reflows inside ResizeObserver callbacks. The detection flow per card:

  1. Remove compact-stacked class
  2. Force reflow (void cardEl.offsetHeight)
  3. Call getBoundingClientRect() on every .pair-left and .pair-right

With 50 visible compact cards each having 3-4 pairs, a pane resize triggers ~400 synchronous layout reads. The compactWidthCache WeakMap bounds this to once per unique width per card, but the first-time cost per width change remains O(pairs × cards).

Proposed solution

Batch the wrapping detection into a single read-then-write pass across all compact cards, matching the pattern syncResponsiveClasses already uses:

  1. Write phase: Remove compact-stacked from all compact cards with cache misses
  2. Single forced reflow
  3. Read phase: Run hasWrappedPairs() on all cards, collect results
  4. Write phase: Apply compact-stacked where needed, update caches

This collapses N forced reflows into 1.

Affected code

  • src/bases/shared-renderer.ts — Bases per-card RO callback
  • src/shared/card-renderer.tsx — Datacore per-card RO callback
  • src/shared/property-helpers.tshasWrappedPairs()

Context

Session c3322c8e-cf10-459c-bc94-2060a0ef89ec — triaged as 5.2 (cache-bounded burst, marginal gain vs restructuring cost).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

Labels

Feature requestRequest for new feature or improvement🏠 BasesAffects Obsidian Bases views🔍 DatacoreAffects Datacore query views🟢 Low priorityWould be nice but not important

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions