mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
perf: reduce browsing rerenders and startup cost (#1189)
* chore(profiling): collect serializable react-scan reports * perf(routing): rerender only when directory winner changes * perf(zustand): remove shallow warning hot path * perf(state): narrow directory lifecycle updates * perf(home): avoid redundant stats render work * perf(posts): isolate live loading subscriptions * perf(chrome): skip unchanged shell rerenders * fix(profiling): drop unsupported render metric * perf(feeds): skip unchanged loading state renders * perf(home): stop resolved stats collector renders * chore(agent run): record rerender verification * perf(home): defer stats requests until metadata resolves * perf(startup): load protocol modules on demand * chore(agent run): record acquisition and startup profiles
This commit is contained in:
@@ -16,10 +16,14 @@ Two-layer profiling: browser-level symptoms (Web Vitals, long tasks, scroll jank
|
||||
|
||||
### react-scan (already configured)
|
||||
|
||||
The app has `react-scan` set up in `src/lib/react-scan.ts` with `report: true`. In dev mode it:
|
||||
`src/lib/react-scan.ts` runs react-scan in dev mode. It:
|
||||
- Highlights rerendering components visually (toolbar + overlay)
|
||||
- Tracks per-component render counts and times internally
|
||||
- Exposes `window.__getReactScanReport()` for programmatic collection
|
||||
- Accumulates per-component render counts and times via react-scan's `onRender` option
|
||||
- Exposes `window.__getReactScanReport()` and `window.__resetReactScanReport()` for programmatic collection
|
||||
|
||||
`__getReactScanReport()` returns a plain object: `{ ComponentName: { count, time } }`.
|
||||
|
||||
**Do not use react-scan's own `getReport()`.** It reads `Store.legacyReportData`, which react-scan 0.5.3 never writes to, so it always returns an empty `Map`. The live `Store.reportData` is no better: it is only populated while the toolbar is visible *and* a component is manually focused in the inspector, neither of which holds under automation. The app's `onRender` collector exists precisely because of this. Also note a `Map` cannot be serialized — `JSON.stringify(new Map())` is `"{}"` regardless of contents — which is why the collector returns a plain object.
|
||||
|
||||
The profiler's `addInitScript` sets `window.__PROFILING__ = true` before the app loads, which tells react-scan to disable its toolbar and sounds during automated runs.
|
||||
|
||||
@@ -160,4 +164,4 @@ playwright-cli -s=prof-3 close 2>/dev/null
|
||||
- **addInitScript persistence**: Instrumentation re-injects automatically in each new document.
|
||||
- **Tracing**: Each subagent produces a `trace.zip` viewable in [Trace Viewer](https://trace.playwright.dev).
|
||||
- **Board codes**: `biz`, `pol`, `g`, `a`, `v`, etc. map to community addresses via the directory.
|
||||
- **Without react-scan**: If `__getReactScanReport` returns null, the profiler falls back to commit counts + render bursts (still useful, just no component names).
|
||||
- **Empty react-scan report**: react-scan is a dynamic import, so `__getReactScanReport()` returns `{}` for the first moment after a `goto`. If it is empty, wait ~1s and re-read before falling back to commit counts + render bursts (still useful, just no component names).
|
||||
|
||||
Reference in New Issue
Block a user