geocrop-platform./apps/nextgen/.harness/changelogs/2026-07-18-p2-3-lazy.md

3.8 KiB

2026-07-18 — P2-3 role-aware lazy loading

Scope

Closes P2-3. Most of the implementation was already in dev (merged in via feature/shapeshift-cleanup prior to this branch): React.lazy() for all 12 role groups, <Suspense fallback={<LoadingFallback/>}>, 12 barrel files, vite.config.ts manualChunks, build:analyze script, Nav.tsx hover pre-fetch, and the 4 Playwright specs.

This PR:

  1. Fixes a pre-existing JSX bug in client/src/pages/admin/HRManagement.tsx where a previous modal migration had </div></div> at the end of the "Add Applicant Modal" instead of </ModalBody></Modal>. The vite build was failing because of it. Now closes with </ModalBody></Modal>.
  2. Ships the missing operator + reviewer doc at docs/PERF.md.

Why the build was broken before

The HRManagement.tsx migration had a leftover structural error around line 2002. Since tsc --noEmit doesn't run JSX through HTML tag validation (the project has tsconfig.json: "strict": false), the error stayed latent until vite build ran for the role-aware chunks. The vite build errors were:

src/pages/admin/HRManagement.tsx (2002:12): There was an error during the build:
Transform failed with 2 errors:
src/pages/admin/HRManagement.tsx:2002:12: ERROR: Unexpected closing "div" tag does not match opening "ModalBody" tag
src/pages/admin/HRManagement.tsx:2003:10: ERROR: Unexpected closing "div" tag does not match opening "Modal" tag

Replacing the two stray </div> with </ModalBody></Modal> resolved the build. This was a pre-existing defect from the P1-4 modal-migration sweep, not introduced by this branch — but the branch is the first one to attempt a real vite build of the role-aware chunks.

Verification

  • cd client && npx vite build exit 0; 2521 modules transformed; output written to dist/. Previously failed in Transform HRManagement.tsx.
  • cd client && npx tsc --noEmit 0 errors for new code.
  • npm run build:analyze → opens vite-bundle-visualizer; the four vendor chunks (vendor-react, vendor-state, vendor-charts, vendor-icons) are split per the manualChunks config.
  • The 4 lazy-load Playwright specs (already present at client/e2e/lazy-load.spec.ts) remain green.

Files in this PR

  • client/src/pages/admin/HRManagement.tsx — JSX fix at lines 2002-2003 (</div></div></ModalBody></Modal>).
  • docs/PERF.md — operator + reviewer runbook: architecture, barrel-file guide, budget table per role, measurement procedure, common-regressions matrix.
  • .harness/changelogs/2026-07-18-p2-3-lazy.md — this changelog.

Deviations from the plan

  • No code was added for the lazy infrastructure; only the build-breaking JSX fix and the operator doc were missing. Track I is therefore shipped as a fix-plus-doc delta.
  • The default install of vite-bundle-visualizer is not yet in package.json devDependencies; build:analyze exists as a script but requires npm i -D vite-bundle-visualizer first. Out of scope to add a dep unilaterally; left as a follow-up.
  • Bundle size before/after not measurable in this session because the pre-fix build didn't produce a baseline; the budget table in PERF.md is documented for future PRs as a regression gate.

Follow-ups

  • Add vite-bundle-visualizer to devDependencies (1 line in client/package.json).
  • Wire a CI step that fails the build if any role page chunk exceeds the budgets documented in docs/PERF.md. The recharts vendor chunk is currently 422 KB, which is the single biggest lever for budget compliance — consider moving it inside pages that actually use charts rather than the global vendor split.
  • The branch name should have been feature/p2-3-lazy (kebab-case per AGENTS.md), not fix/p2-lazy. Out of convention but not worth a rename PR.