Files
MultiRoombaRover/perf/ROOT_PERFORMANCE_SUMMARY.md
T

187 lines
4.1 KiB
Markdown

# `/` Performance Investigation Summary
This is the high-level handoff for the default route at:
```sh
https://rover.otter.land/
```
The detailed issue writeups live in `perf/issues/`.
## Main Finding
The `/` page is doing too much main-thread work for low-end devices. On the current powerful
machine it can appear smooth, but CPU throttling shows real risk for mobile and weaker
computers.
The biggest measured problem is repeated global input listener churn. The broader underlying
theme is that high-frequency live data and broad React context invalidation cause many parts
of the page to rerender or recommit DOM attributes.
## Key Measurements
### Clean `/` Profile, 8x Mobile CPU Throttle
Artifact:
```sh
perf/results/2026-06-11T03-15-51-398Z/report.json
```
Results:
```txt
average frame interval: ~140ms
p95 frame interval: ~166.8ms
p99 frame interval: ~383.4ms
long tasks: 67
event listener delta: +13,481
JS heap delta: +22.76MB
ScriptDuration delta: ~35.85s
TaskDuration delta: ~52.88s
```
Top notable CPU self-time included:
```txt
removeEventListener ~1.30s
addEventListener ~0.94s
```
### Listener Audit
Artifact:
```sh
perf/results/2026-06-11T03-03-31-625Z-listeners/listener-report.json
```
Worst churn:
```txt
keydown adds=8040 removes=8039
keyup adds=8040 removes=8039
blur adds=8040 removes=8039
gamepadconnected adds=8040 removes=8039
gamepaddisconnected adds=8040 removes=8039
```
### `/` Runtime Audit, 6x Mobile CPU Throttle, 30s
Artifact:
```sh
perf/results/2026-06-11T03-21-51-263Z-root-runtime/root-runtime-report.json
```
Results:
```txt
average frame interval: ~88ms
p95 frame interval: 150ms
p99 frame interval: 183ms
long tasks: 18
WebSocket messages: at least 1000 sampled
WebSocket bytes: ~798KB sampled
DOM mutation records: 41,062
DOM attribute records: 40,761
```
Top sampled WebSocket events:
```txt
log:entry 526
sensorFrame 306
commandAck 145
session:sync 5
```
### `/` Runtime Audit With Mutation Targets, 6x Mobile CPU Throttle, 18s
Artifact:
```sh
perf/results/2026-06-11T03-22-44-714Z-root-runtime/root-runtime-report.json
```
Results:
```txt
average frame interval: ~116.6ms
p95 frame interval: ~166.7ms
p99 frame interval: ~316.6ms
long tasks: 16
DOM mutation records: 18,758
DOM attribute records: 18,490
```
Top WebSocket events:
```txt
log:entry 850
sensorFrame 277
commandAck 200
session:sync 23
```
Top mutation targets:
```txt
input.accent-emerald-400 name 5300
input.accent-emerald-400 type 2650
field-input name ~1300 each
div.h-full style 1238
path d 621
path fill 619
```
## Ordered Work Plan
1. Fix `KeyboardInputManager` and `GamepadInputManager` listener churn.
2. Split/stabilize `ControlContext` so action consumers do not rerender on every state change.
3. Batch or gate `log:entry` socket updates.
4. Throttle visual telemetry rendering.
5. Memoize or lazy-mount `ReplaySourcesPanel`.
6. Split and memoize chat composer/nickname form.
7. Clean up or share timers.
## Reproduction Commands
Install Playwright dependency if missing:
```sh
npm install --prefix perf playwright@1.60.0
npx playwright install chromium
```
Clean CPU profile:
```sh
CPU_THROTTLE=8 VIEWPORT=390x844 MOBILE=1 node perf/live-cpu-profile.mjs https://rover.otter.land/ perf/results
```
Listener audit:
```sh
node perf/live-listener-audit.mjs https://rover.otter.land/ perf/results
```
Runtime audit:
```sh
CPU_THROTTLE=6 VIEWPORT=390x844 MOBILE=1 SAMPLE_MS=30000 node perf/live-root-runtime-audit.mjs https://rover.otter.land/ perf/results
```
Runtime audit with shorter mutation target sample:
```sh
CPU_THROTTLE=6 VIEWPORT=390x844 MOBILE=1 SAMPLE_MS=18000 node perf/live-root-runtime-audit.mjs https://rover.otter.land/ perf/results
```
## Notes
The `perf/results/2026-06-11T03-11-39-596Z-route-sweep/` route sweep includes `/spectate`,
`/mini`, `/display`, and `/scanner`. Those are not the current priority. Use them only for
context.