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:
Tommaso Casaburi
2026-07-30 00:29:12 +07:00
committed by GitHub
parent 27cc4767c6
commit da03239bb2
33 changed files with 1274 additions and 380 deletions
+10
View File
@@ -974,6 +974,16 @@ If uncertain, ask the developer before adding an entry.
- **Impact:** Notarization aborts after a successful signing pass; the error message looks like a signing failure and invites debugging the certificate/keychain instead of the real cause. Any tool that shells out to `codesign` with a bare relative path can hit this because the app is literally named `5chan`.
- **Mitigation:** Keep the yarn patch `.yarn/patches/@electron-notarize-npm-2.5.0-*.patch` (backport of electron/notarize#245, prefixes the basename with `./`) until electron-forge depends on `@electron/notarize` >= 3.x. When invoking `codesign` manually on the app bundle, always use an absolute or `./`-prefixed path.
- **Status:** confirmed
### react-scan's `getReport()` is dead API and can never return data
- **Date:** 2026-07-27
- **Observed by:** contributor + Claude
- **Context:** Running the `profile-browsing` skill against a branch to measure excessive rerenders, and getting no component data back
- **What was surprising:** Three independent failures stacked up silently. (1) `getReport()` returns `Store.legacyReportData`, which react-scan 0.5.3 initializes as an empty `Map` and never writes to anywhere in the bundle. (2) The live `Store.reportData` is only populated inside `if (options.showToolbar !== false && Store.inspectState.value.kind === 'focused')` — but the profiler sets `__PROFILING__=true`, which sets `showToolbar: false`, and `'focused'` requires a human clicking the inspector onto one component, so it is unreachable under automation. (3) `getReport()` returns a `Map`, and `JSON.stringify(new Map())` is `"{}"` regardless of contents, so the skill's collection line would have printed `{}` even if data existed. The skill and profiler agent additionally claimed the app was configured with `report: true`; react-scan 0.5.3 has no `report` option at all, and passing one logs `[React Scan] Invalid options: - Unknown option "report"`.
- **Impact:** Every profiling run reported zero react-scan component data without erroring, so rerender hotspots looked invisible and profiling silently degraded to raw commit counts.
- **Mitigation:** `src/lib/react-scan.ts` now accumulates render data through react-scan's `onRender` option, which is only skipped when `isPaused && inspectorInactive` (verified `isPaused: false` with the toolbar off). It exposes `window.__getReactScanReport()` returning a plain, JSON-serializable object and `window.__resetReactScanReport()`. Never reintroduce `getReport()`, and never `JSON.stringify` a `Map`. Set `window.__PROFILING_UNNECESSARY__ = true` to opt into `trackUnnecessaryRenders`; it is off by default because it adds overhead that skews the `time` field.
- **Status:** confirmed
```
---