Speed up compositing and gesture start without behavior changes
- Memoize each operation's choreography effect set in a computed, so nodes sharing an edge stop re-evaluating it (linear, not quadratic, in chain depth). - Cache the scene viewport and refresh it from a ResizeObserver and at each begin(), instead of measuring the container per node per frame. - Index operations by origin key so outgoing lookups no longer scan every operation; all map changes go through attach()/detach(). - Resolve px and % gesture edge distances arithmetically; only other CSS lengths use the off-screen probe. Verified in Chromium to match the probe within its 1/64px layout rounding. The differential suites against main still match exactly. Benchmarks vs main: styleForNode 2.0x (3 live ops) and 2.4x (10 live ops), rendered frames 1.14x. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Faarh2Ts6StJPcz2mRiHiR
This commit is contained in:
@@ -103,12 +103,16 @@ export const pointOf = (
|
||||
const nonNegative = (value: number) =>
|
||||
Number.isFinite(value) ? Math.max(0, value) : 0;
|
||||
|
||||
const PIXELS = /^\s*(-?(?:\d+\.?\d*|\.\d+))px\s*$/;
|
||||
const PERCENT = /^\s*(-?(?:\d+\.?\d*|\.\d+))%\s*$/;
|
||||
|
||||
/**
|
||||
* Resolve an arbitrary CSS length against a box with the gesture host's size.
|
||||
* Resolve a CSS length against a box with the gesture host's size.
|
||||
*
|
||||
* A short-lived off-screen box lets the browser handle `rem`, viewport units,
|
||||
* percentages, `calc()`, and `clamp()` consistently. This runs only during
|
||||
* pointer-down for edge-constrained definitions.
|
||||
* Numbers, pixel lengths, and percentages are computed directly. Anything
|
||||
* else (`rem`, viewport units, `calc()`, `clamp()`) is measured with a
|
||||
* short-lived off-screen box so the browser resolves it exactly. This runs
|
||||
* only during pointer-down for edge-constrained definitions.
|
||||
*/
|
||||
export const resolveCssDistance = (
|
||||
distance: OriginGestureDistance,
|
||||
@@ -117,6 +121,13 @@ export const resolveCssDistance = (
|
||||
bounds: OriginRect,
|
||||
): number => {
|
||||
if (typeof distance === "number") return nonNegative(distance);
|
||||
const pixels = PIXELS.exec(distance);
|
||||
if (pixels) return nonNegative(Number(pixels[1]));
|
||||
const percent = PERCENT.exec(distance);
|
||||
if (percent) {
|
||||
const size = axis === "horizontal" ? bounds.width : bounds.height;
|
||||
return nonNegative((Number(percent[1]) / 100) * size);
|
||||
}
|
||||
|
||||
const document = host.ownerDocument;
|
||||
if (!document.body) return Math.max(0, Number.parseFloat(distance) || 0);
|
||||
|
||||
Reference in New Issue
Block a user