perf: reuse a stationary reading mask during scrolling

Keep native document geometry while translating content behind one viewport fade. Preserve navigation, focus, media preloading, and Static cleanup without changing 3D quality or render resolution.

Validated assets, types, production builds, prerendered artifacts and transfer budgets; compared 64 layouts and checked 87 live interactions plus uncached media and repeated cleanup. High improved from 71.7 to 101.4 FPS at DPR 1 and 47.8 to 62.2 FPS in the full-size DPR 1.5 window, with occasional sub-60 intervals still remaining.
This commit is contained in:
2026-09-05 17:42:19 +03:00
parent d48e9017cc
commit 15bcdf7cec
5 changed files with 324 additions and 185 deletions

View File

@@ -52,3 +52,45 @@ No production changes were made during investigation. All browser runs
inventoried and reused the single existing Chrome tab/window. Temporary
scripts, traces, screenshots, and detailed measurements remain in the ignored
`.perf/investigation/` folder; no tests or frameworks were added.
## Stationary reading fade implementation
The native document retains its original height and anchor coordinates. One
sticky reading viewport owns the fade; the content translates behind it.
The opening fade still advances with scrolling, then stays fixed. Live heading
and project-header entrance animations are replaced by this reading edge,
while Static mode retains normal document flow and existing styles.
Media observers use the reading viewport as their live root. Images use a
1250px lookahead; an uncached probe confirmed they load by 1200px before the
viewport, matching the baseline probe. Video activation retains its 300px margin. Static cleanup
restores native lazy loading. Car, terrain, bloom, render resolution, audio,
content, and shared journey calculations are unchanged.
Validation: 64 chapter/layout comparisons across eight viewport sizes retained
page height and anchor geometry within 0.002px. All 87 live interaction checks
passed without errors, hidden headings, or horizontal overflow. Repeated
quality changes retained stable listener/resize-observer counts and restored
Static styles. Graphics allocation counts matched the preceding production
baseline; this is not a claim that all browser/driver allocations are released.
Uncached media-boundary and image-attribute cleanup checks passed. Approved
assets, types, both builds, prerendering, artifacts, and transfer budgets passed.
Independent code review found no remaining concrete issues. All browser work
reused the same single Chrome tab and window.
Final presented-frame measurements on the same hardware and effective High:
| Scrolling condition | Before | After | Before/after p95 interval |
| --- | ---: | ---: | ---: |
| 1440 × 900 CSS, DPR 1, 45 seconds | 71.7 FPS | 101.4 FPS | 25 / 16.7 ms |
| Maximized 1707 × 944 CSS, DPR 1.5 | 47.8 FPS | 62.2 FPS | 33.3 / 20.8 ms |
The maximized baseline ran 32 seconds; the final implementation ran 60 seconds.
The same first 32-second route cycle was also compared in the temporary
measurement evidence. The 60-second run's lowest complete one-second interval
was 58 FPS: this improves full-resolution scrolling but does not guarantee
locked 60 FPS. Both conditions retained their original canvas dimensions
(1425 × 900 and 2538 × 1416 respectively). Before the final image-preload
compatibility adjustment, Medium measured 81.4 → 125.7 presented FPS at DPR 1,
and native wheel input independently confirmed the scrolling improvement.
Temporary implementation diagnostics remain in ignored `.perf/fade/` files.