diff --git a/docs/performance/2026-09-05-scroll-investigation.md b/docs/performance/2026-09-05-scroll-investigation.md new file mode 100644 index 0000000..54bd2ee --- /dev/null +++ b/docs/performance/2026-09-05-scroll-investigation.md @@ -0,0 +1,54 @@ +# Scrolling performance investigation + +Production baseline: `f3f2b03` on `codex/portfolio-performance`. + +Hardware: ASUS ROG Strix SCAR 16 G635LX, Intel Core Ultra 9 275HX, +hardware-backed ANGLE Intel Mesa ARL graphics, Chrome 152. Viewport +1440 × 900, DPR approximately 1, canvas 1425 × 900. Effective High +and Medium tiers were recorded throughout each measurement. Phone testing +is deferred. + +## Findings + +Matched 45-second High-quality scrolling runs after five seconds of warm-up: + +| Condition | Presented frames/second | p95 presentation interval | +| --- | ---: | ---: | +| Normal page | 71.4 | 25 ms | +| Chapter masks disabled | 116.1 | 12.5 ms | + +The 3D scene, render resolution, bloom, and motion were unchanged. Disabling +masks changes the appearance and was diagnostic only. Native wheel scrolling +reproduced the pattern. A separate 32-second Medium comparison measured +80.2 versus 142.4 animation callbacks/second, with p95 intervals of 20.9 +versus 12.4 ms. + +Full traces showed approximately 8,800 versus 840 page raster operations. +Static masks performed substantially better than continually changing masks. +Layer promotion, paint containment, and viewport-sized mask images did not +resolve the slow frames. Whole-world GPU samples had a median of 2.7 ms; +JavaScript scene submission was approximately 0.7 ms. Removing the entire +car or terrain did not resolve the 25 ms p95 scrolling intervals. Bypassing +bloom helped less than disabling masks and still exceeded the 60 FPS budget. + +The absolute rate in this session exceeded the earlier approximately 45 FPS +control, including when rerunning the original measurement harness. The +reason for that session difference was not isolated. These are matched +same-session diagnostic comparisons, not newly shipped improvements. +Detailed tracing adds overhead; GPU timer intervals may include stalls and +cannot be added directly to displayed frame intervals. + +## Implementation direction + +Keep the fades visually close while separating the stationary reading edge +from scrolling content, allowing rasterized content and mask data to be +reused. Preserve native document scrolling, navigation, focus, content, +3D quality, audio, and shared journey outputs. Validate responsive layouts, +short viewports, reversals, quality changes, Static mode, reduced motion, +resource cleanup, and sustained rendering before retaining the change. + +The user allows modest visual differences if the result does not look worse. +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.