Skip to main content
All Docs
FeaturesBlockManOSUpdated March 26, 2026

Route-level code splitting for the dashboard

Route-level code splitting for the dashboard

Released in v1.0.47 · PERF-01

What changed

All 15 dashboard pages now use next/dynamic to lazy-load their client components. Previously every page statically imported its client component, which caused the browser to download the JS for every dashboard feature on the first page load — even modules the user may never visit.

With route-level code splitting, each feature's JavaScript is delivered as a separate chunk and fetched only when the user navigates to that route.

How it works

Each dashboard page.tsx follows the same pattern:

import nextDynamic from "next/dynamic";
import { Skeleton } from "@/components/ui/skeleton";

const BudgetDashboardClient = nextDynamic(
  () => import("./client").then((m) => ({ default: m.BudgetDashboardClient })),
  {
    ssr: false,
    loading: () => (
      <div className="space-y-4">
        <Skeleton className="h-10 w-64" />
        <Skeleton className="h-64 w-full" />
        <Skeleton className="h-64 w-full" />
      </div>
    ),
  }
);

Key decisions

OptionValueReason
ssrfalseAll dashboard components use useSession and tRPC hooks, which cannot run during server-side rendering
.then((m) => ({ default: m.ExportName }))Named → default re-exportnext/dynamic requires a default export; this adapter pattern handles named exports correctly
loading<Skeleton /> placeholderShown instantly while the chunk is in-flight, preventing layout shift and giving immediate visual feedback

Affected routes

RouteLazily loaded component
/dashboard/budgetBudgetDashboardClient
/dashboard/bank-reconciliationBankReconciliationClient
/dashboard/gdprGdprDashboardClient
/dashboard/irish-legislationIrishLegislationClient
/dashboard/sinking-fundSinkingFundClient
/dashboard/agmAgmClient
/dashboard/communicationsCommunicationsClient
/dashboard/complianceComplianceDashboardClient
/dashboard/maintenanceMaintenanceDashboardClient
/dashboard/documentsDocumentsClient
/dashboard/service-chargesServiceChargeDashboardClient
/dashboard/reportsReportsDashboardClient
/dashboard/ppmPpmDashboardClient
/dashboard/psraPsraClient
/dashboard/annual-planAnnualPlanClient

Skeleton loading component

A new Skeleton UI component (@/components/ui/skeleton) was added to support the loading states. It renders animated placeholder shapes that match the rough layout of each dashboard page, displayed while the route chunk is fetching.

User experience

  • First navigation to any dashboard route — the page shell renders immediately from the server; the Skeleton placeholder appears while the feature chunk loads; the full component mounts once the download completes.
  • Subsequent navigations — chunks are cached by the browser and module system, so revisiting a route is instant.
  • Users who never visit a route — never download its JavaScript bundle at all.