chore(planning): phase 4 done — performance audit landed

Captured Playwright+PerformanceObserver perf metrics against prod
(/api/version=1.4.13) at 2026-05-09T14:14Z. Top 2 wins shipped
inline (Recharts deferred-import on /insights, checklist queries
gated on post-onboarding state); Recharts replacement deferred to
v1.5.1 because v1.5 forbids new deps.

Wins: bb2b1de + 519e36e. Audit doc: 41fa203.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-09 16:24:39 +02:00
1 parent 41fa2032ae
commit ad8fe5a60d
2 files changed
+75 -3

No files matched your search

+7 -3
View File
@@ -51,9 +51,13 @@ Last update: 2026-05-09T16:10:00+02:00
## Phase 4 — Performance audit
- [ ] Playwright capture: /, /settings/integrations, /admin, /insights at desktop+mobile
- [ ] Report at `docs/audit/v15-performance.md`
- [ ] Top 3 wins identified, <30 LOC ones implemented inline
- [x] Playwright capture: /, /settings/integrations, /admin, /insights at desktop+mobile (prod=1.4.13, captured 2026-05-09T14:14Z)
- [x] Report at `docs/audit/v15-performance.md` — commit `41fa203`
- [x] Top 3 wins identified, <30 LOC ones implemented inline:
- W1 commit `bb2b1de` — defer Recharts ScatterChart imports on `/insights` via `next/dynamic` (~108 KiB initial-JS savings)
- W2 commit `519e36e` — skip checklist API fetches once onboarding is complete (~950 ms network savings on dashboard)
- W3 deferred to v1.5.1 — replace Recharts (effort L + needs new dep)
- Result: ok / commits `bb2b1de 519e36e 41fa203`
- Detailed report: `.planning/phase-4-report.md`
## Phase 4b — Admin Panel refactor (Settings-style dynamic routes)
+68
View File
@@ -0,0 +1,68 @@
# Phase 4 — Performance audit (v1.5 marathon)
**Status**: done
**Finished**: 2026-05-09T16:30+02:00
**Full report**: [docs/audit/v15-performance.md](../docs/audit/v15-performance.md)
## What got measured
Standalone Playwright + PerformanceObserver script (one-shot, lives at
`/tmp/v15-perf-measure.mjs`, not committed) captured nav timing, LCP,
TBT, longtask count, full Resource Timing list and a per-response
content-length fallback (Cloudflare strips Content-Length on chunked
responses) against production (`/api/version` = `1.4.13`) at
`2026-05-09T14:14:48Z`. Marc's session cookie was injected pre-nav.
Four pages (`/`, `/settings/integrations`, `/admin`, `/insights`) each
loaded twice — `1920×1080` desktop and Pixel 5 mobile.
## Headline numbers
The dashboard is the heaviest page: 425 KiB JS, 2.83 s LCP desktop,
624 ms TBT (one longtask, dashboard hydration). `/insights` is
comparable (419 KiB JS, ~108 KiB of which is Recharts pulled in
eagerly). `/admin` and `/settings/integrations` are lean (~290 KiB JS,
< 2 s LCP). The dominant single-dependency cost everywhere is
**Recharts** (~108 KiB Brotli per chart-using page).
## Wins implemented inline
1. **`bb2b1de` — `perf(insights): defer Recharts ScatterChart imports
via next/dynamic`** — moves the seven recharts symbols (ScatterChart,
Scatter, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer)
off the eager imports of `src/app/insights/page.tsx` and onto
per-symbol `next/dynamic({ ssr: false })`. Same shape as the existing
HealthChart/MoodChart pattern in the same file.
2. **`519e36e` — `perf(dashboard): skip checklist API fetches once
onboarding is complete`** — gates the `withings/status` and
`notifications/preferences` queries inside
`getting-started-checklist.tsx` on
`user.onboardingCompletedAt == null`. Saves ~950 ms of network on
every dashboard load for established users.
The audit doc was committed in **`41fa203`**.
## Wins deferred
- **Recharts replacement** (~108 KiB savings on every chart-using
page). Effort is L (every chart in `src/components/charts/` needs
rewrite + a new dep). Tagged for **v1.5.1** because v1.5's no-new-deps
hard rule blocks it.
## Not done / acknowledged
- Local `pnpm build` cannot complete on this machine due to the Node-25
turbopack `Cannot read private member #state…` regression noted in
`CLAUDE.md`. Verification therefore lives in static code review and
will be re-confirmed against prod once v1.5.0 deploys.
- `pnpm typecheck` reports two errors in `e2e/mobile-viewport.spec.ts`
(concurrent Phase 3 work) — left untouched per the "do not touch
e2e/" constraint.
- `pnpm test` (95 files / 733 tests) and `pnpm lint` (0 errors,
pre-existing warnings only) are clean for the files I touched.
## Files committed
- `src/app/insights/page.tsx` — recharts symbols → `next/dynamic`
- `src/components/onboarding/getting-started-checklist.tsx` — checklist
query gating
- `docs/audit/v15-performance.md` — full audit