Faster Dashboards: How We Shrunk the Initial JS Bundle
Faster Dashboards: How We Shrunk the Initial JS Bundle
Release: v0.1.42 · Control: PERF-01 · Category: Performance
The Problem
Four of the heaviest pages in the application were being bundled into the initial JavaScript payload sent to every user on every page load — even if they never visited those pages in a given session:
| Page | Approx. Size |
|---|---|
| Billing | 31 KB |
| Sanctions | 25 KB |
| Matches | 18 KB |
| Settings | 19 KB |
That adds up to roughly 93 KB of JavaScript that the browser had to download, parse, and execute before any page became interactive — regardless of which page the user actually landed on. On slow or mobile connections this created a measurable delay before the UI responded to input.
On top of that, @tanstack/react-query was listed in package.json and included in the bundle, despite never being used anywhere in the codebase.
The Fix
Dynamic Imports with next/dynamic
Each of the four affected pages was refactored to use Next.js's built-in dynamic() wrapper. The real page component is now code-split into its own chunk and only fetched when a user actually navigates to that route.
// Example: src/app/dashboard/billing/page.tsx
import dynamic from 'next/dynamic';
import { PageSkeleton } from '@/components/ui/page-skeleton';
const BillingContent = dynamic(
() => import('./billing-content'),
{ loading: () => <PageSkeleton /> }
);
export default function BillingPage() {
return <BillingContent />;
}
The same pattern was applied to the sanctions, matches, and settings pages.
Loading Skeletons
Passing { loading: () => <PageSkeleton /> } to dynamic() means users see an instant skeleton layout while the page chunk loads, rather than a blank screen. This keeps the interface feeling responsive even on the first visit.
Removing Dead Dependencies
@tanstack/react-query was removed from package.json. It was installed but never used, contributing bundle weight with zero benefit.
What You'll Notice
- Faster time-to-interactive on the initial app load — the browser now has significantly less JS to parse before the first page becomes usable.
- Brief skeleton loaders on first navigation to Billing, Sanctions, Matches, or Settings pages. Subsequent visits use the browser's cached chunk.
- No changes to functionality — data, UI behaviour, and navigation are all identical.
Background: Why This Matters for Compliance Tools
Sanctions screening dashboards are often accessed by compliance analysts working under time pressure. Slow load times aren't just a UX inconvenience — they can delay critical decisions. Keeping the initial bundle lean ensures the application is responsive from the moment it loads, regardless of the user's network conditions.