Goal
Defer loading the map library (which is likely the heaviest dependency) so the initial page paint is not blocked by JavaScript that the user may never scroll to.
Background
Map.tsx (and DetailHeritageMap.tsx) are imported statically in TopPage.tsx and HeritageDetailLayout.tsx. If the underlying map library (e.g. Leaflet or similar) is bundled eagerly, it adds significant kilobytes to the initial JS chunk, delaying TTI (Time to Interactive).
What to do
- In
TopPage.tsx: replace the static import { Map } with:
const Map = React.lazy(() => import("./Map"));
Wrap with <Suspense fallback={<div className="h-64 animate-pulse bg-zinc-100 rounded-xl" />}> to show a placeholder while loading
- Apply the same pattern to
DetailHeritageMap in HeritageDetailLayout.tsx
- Verify with
npm run build that the map chunk is now split into a separate file (check dist/ output for a separate chunk)
Files to touch
src/app/features/top/components/TopPage.tsx
src/app/features/top/components/heritage-detail/HeritageDetailLayout.tsx
Acceptance criteria
Goal
Defer loading the map library (which is likely the heaviest dependency) so the initial page paint is not blocked by JavaScript that the user may never scroll to.
Background
Map.tsx(andDetailHeritageMap.tsx) are imported statically inTopPage.tsxandHeritageDetailLayout.tsx. If the underlying map library (e.g. Leaflet or similar) is bundled eagerly, it adds significant kilobytes to the initial JS chunk, delaying TTI (Time to Interactive).What to do
TopPage.tsx: replace the staticimport { Map }with:<Suspense fallback={<div className="h-64 animate-pulse bg-zinc-100 rounded-xl" />}>to show a placeholder while loadingDetailHeritageMapinHeritageDetailLayout.tsxnpm run buildthat the map chunk is now split into a separate file (checkdist/output for a separate chunk)Files to touch
src/app/features/top/components/TopPage.tsxsrc/app/features/top/components/heritage-detail/HeritageDetailLayout.tsxAcceptance criteria
npm run buildproduces a separate JS chunk for the map component