perf: allocation/scan hardening for weaker hardware

Static-analysis follow-ups to the trace-backed fixes; each is cheap
insurance on machines where the profiled headroom doesn't exist.

- highway.js: _makeBundle now mutates one persistent per-instance
  object instead of allocating a fresh ~35-field bundle every rAF
  frame (xN under splitscreen). Object identity is stable and
  meaningless; array fields still swap reference on chart changes,
  which field-identity caches rely on. Contract documented in both
  CLAUDE.mds.
- highway.js: new bsearchTime (lower-bound on .time) windows the
  default 2D renderer's beat-line scan (was O(all beats) per frame);
  bundle.lowerBoundT / bundle.lowerBoundTime expose the searches to
  custom viz so they stop reimplementing visible-window culling.
- highway_3d: localStorage 'h3d_full_sus' polled at ~1 Hz instead of
  every frame (synchronous storage read on the hot path).
- highway_3d: drawLyrics caches the measureText row layout keyed on
  (lyrics ref, line index, shown count, font size, width) — per-frame
  work is now just drawing over cached widths.
- tests/js: bundle source-shape assertions widened to accept the
  assignment form ([:=]) alongside the old object-literal form.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
OmikronApex
2026-07-02 00:02:54 +02:00
co-authored by Claude Fable 5
parent 5239665e2b
commit 77547af110
10 changed files with 208 additions and 128 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ test('bundle exposes handShapes to renderers with flat-list fallback', () => {
const src = fs.readFileSync(HIGHWAY_JS, 'utf8');
assert.match(
src,
/\bhandShapes:\s*\([^)]*_filteredHandShapes[^)]*\)\s*\?\s*_filteredHandShapes\s*:\s*handShapes\b/,
/\bhandShapes\s*[:=]\s*\([^)]*_filteredHandShapes[^)]*\)\s*\?\s*_filteredHandShapes\s*:\s*handShapes\b/,
'bundle must expose handShapes with the _filteredHandShapes-vs-handShapes ternary fallback',
);
});
+1 -1
View File
@@ -20,7 +20,7 @@ function src(file) {
test('highway renderer bundles surface the core lefty flag', () => {
assert.match(
src(HIGHWAY_JS),
/lefty\s*:\s*_lefty/,
/lefty\s*[:=]\s*_lefty/,
'custom renderer bundles must include lefty: _lefty',
);
});
@@ -43,13 +43,13 @@ test('core _makeBundle exposes isPlaying derived from the chart-clock anchor', (
const src = fs.readFileSync(highwayJs, 'utf8');
const fn = extractBlock(src, 'function _makeBundle()');
// Field present in the bundle.
assert.match(fn, /\bisPlaying\s*:/, 'bundle must expose isPlaying');
assert.match(fn, /\bisPlaying\s*[:=]/, 'bundle must expose isPlaying');
// It is computed from the same anchor/advance state getTime() uses, not a
// hardcoded literal — anchor must exist AND the clock must have advanced
// within the interp cap.
assert.match(
fn,
/isPlaying\s*:\s*!Number\.isNaN\(\s*_chartAnchorPerfNow\s*\)/,
/isPlaying\s*[:=]\s*!Number\.isNaN\(\s*_chartAnchorPerfNow\s*\)/,
'isPlaying must gate on a live anchor (_chartAnchorPerfNow not NaN)',
);
assert.match(
+1 -1
View File
@@ -82,7 +82,7 @@ test('draw() only adapts during active playback and feeds the HUD', () => {
test('bundle + canvas sizing use the effective scale, not the raw user value', () => {
const src = fs.readFileSync(highwayJs, 'utf8');
assert.match(src, /renderScale:\s*_effectiveRenderScale\(\)/, 'bundle.renderScale must be the effective scale');
assert.match(src, /renderScale\s*[:=]\s*_effectiveRenderScale\(\)/, 'bundle.renderScale must be the effective scale');
assert.match(src, /canvas\.width\s*=\s*Math\.round\(w\s*\*\s*_effectiveRenderScale\(\)\)/, 'canvas backing store must use effective scale');
});
+2 -2
View File
@@ -51,7 +51,7 @@ test('_makeBundle exposes getNoteState (stable reference, no per-frame alloc)',
const fn = extractBlock(src, 'function _makeBundle()');
// The bundle field must point straight at _noteState — not a fresh
// arrow each frame (the per-frame allocation the review flagged).
assert.match(fn, /getNoteState:\s*_noteState\b/, 'bundle.getNoteState must be the stable _noteState reference');
assert.match(fn, /getNoteState\s*[:=]\s*_noteState\b/, 'bundle.getNoteState must be the stable _noteState reference');
});
test('_makeBundle exposes getNoteStateProvider as a stable reference (feedBack#254)', () => {
@@ -64,7 +64,7 @@ test('_makeBundle exposes getNoteStateProvider as a stable reference (feedBack#2
// identity-based guards in renderer code.
assert.match(
fn,
/getNoteStateProvider:\s*_getNoteStateProvider\b/,
/getNoteStateProvider\s*[:=]\s*_getNoteStateProvider\b/,
'bundle.getNoteStateProvider must be the stable _getNoteStateProvider reference (not a per-frame arrow)'
);
// Sanity: the stable accessor exists per-createHighway-instance