Skip to content

Limit dimension-only CSS variable recalculation to affected elements - #51

Merged
danwalmsley merged 3 commits into
mainfrom
codex/css-variable-resize
Sep 9, 2026
Merged

danwalmsley merged 3 commits into
mainfrom
codex/css-variable-resize

Conversation

@danwalmsley

@danwalmsley danwalmsley commented Sep 9, 2026 •

Copy link
Copy Markdown
Collaborator

Dragging Kestrel’s properties divider updates the root --right-width variable, but currently rebuilds styles throughout the root subtree. Limit recalculation to the mutation root and dimension consumers when dependencies are safe. Preserve style batching and synchronous CSSOM barriers; mixed mutations, aliases, inherited properties, pseudo-elements, shadow DOM, and style-attribute dependencies retain the full path.

Explicit dimension inheritance also retains ancestor-first subtree recalculation, including var() fallbacks resolving to inherit. Replay inline width/height inheritance during a full cascade so descendants follow their parent while preserving stylesheet priority.

The full-subtree setter exists on main and dates to commit 869f1a0 (July 20), predating the recent Windows work. This identifies a longstanding invalidation bottleneck; it does not claim a complete historical frame-rate bisect.

After the review correction, three alternating Windows runs of the included 1,000-item DOM benchmark measured 29.92 ms baseline versus 3.17 ms fixed median synchronous resize time (about 89% less). This measures style/layout, not full Kestrel FPS or physical presentation.

Validation:

  • Reproduced the review regression before fixing it.
  • Added 24 inheritance combinations covering stylesheet/inline declarations, literal/var-fallback inheritance, one/three descendant levels, and setProperty/removeProperty/empty setter, plus an inline-priority case.
  • All 14 focused compatibility checks and all three parser suites pass on the corrected patch. The baseline control independently confirms an older literal-inline inheritance issue fixed here as well.
  • The full native suite fails on unchanged main and the patch at the existing iframe preparation did not overlap discovery with outer script work assertion; that unrelated test remains unchanged.

Commands, history, and raw results are in docs/validation/css-variable-resize.md. This PR is based directly on main and includes no Windows WebGPU, pacing, font-cache, or Kestrel fixture changes.

@danwalmsley

Copy link
Copy Markdown
Collaborator Author

The optimization looks beneficial and complements #50, but I found a correctness regression that should be fixed before merging.

At cbd32569, the consumer selection in recascade_dimension_custom_property only includes direct variable consumers. It misses descendants that inherit the resulting dimension:

<style>
  :root { --size: 100px; }
  .parent { width: var(--size); height: var(--size); }
  .child { width: inherit; height: inherit; }
</style>
<div class="parent" id="parent"><div class="child" id="child"></div></div>

After an initial geometry read, run:

document.documentElement.style.setProperty('--size', '200px');

Observed [parent width, child width, child height]:

Both width: inherit and height: inherit need dependency propagation. Please recascade indirect dependents in ancestor-first order, or fall back to the affected subtree when those dependencies cannot be tracked safely. The same rule should account for other supported dimension dependencies, rather than assuming that a non-inherited-by-default property cannot affect descendant styles.

Please add isolated regressions for stylesheet and inline inheritance, multiple inheritance levels, and variable updates through setProperty, removeProperty, and the empty-value setter. The existing dimension-variable-compatibility filter passed locally despite this regression.

Performance evidence is encouraging: one local macOS run of the included 1,000-item benchmark measured a median of 17.62 ms on the baseline versus 1.56 ms with this PR, across 60 samples after warm-up. This is a single synchronous style/layout microbenchmark comparison, not an application FPS measurement.

@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Sep 9, 2026
@danwalmsley
danwalmsley merged commit c2ceb39 into main Sep 9, 2026
4 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant