Skip to content

Dynamic Import and Route-Level Code Splitting #561

Description

@Kingsman-99

Description

Several heavy components — the rich-text editor, the Stellar SDK transaction builder, and charting libraries — are included in the initial JS bundle even for routes that do not use them, inflating the First Contentful Paint on all pages. Splitting these via next/dynamic ensures each route only loads code it actually needs.

Technical Context

next/dynamic with { ssr: false } applied in src/components/invoice/NotesEditor.tsx (wrapping the rich-text library), src/components/analytics/TrendChart.tsx (wrapping the chart library), and src/lib/stellar/transactionBuilder.ts (imported dynamically in src/app/invoice/[id]/sign/page.tsx). A next/bundle-analyzer configuration in next.config.js (behind the ANALYZE=true env var) is added to make bundle composition auditable in CI. Loading fallbacks for each dynamic import are defined using the loading option with accessible aria-busy spinner markup.

Acceptance Criteria

  • Running ANALYZE=true npm run build produces an interactive bundle report; the rich-text and chart libraries do not appear in the initial route chunk
  • The invoice list and invoice creation pages each load without downloading the chart library or rich-text editor bundle
  • Each dynamically imported component has a loading fallback that renders a spinner with role="status" and aria-label
  • Total initial JS transferred for the dashboard route is reduced by at least 15% versus the pre-change baseline, measured with next build size output
  • TypeScript types are preserved across the dynamic import boundary (no loss of prop types or return types)
  • All CI checks (npm test, npm run build, ESLint/TypeScript) pass and the branch has no merge conflicts

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions