All Docs
FeaturesCalmony Sanctions MonitorUpdated March 11, 2026

Faster Dashboards with Bundle Splitting

Faster Dashboards with Bundle Splitting

Release: v0.1.41 · Performance · PERF-01

Background

The sanctions screening dashboard is a multi-page application. Before this release, every page's JavaScript — billing, sanctions, matches, and settings — was included in the initial bundle delivered to the browser on first load. This meant users paid the full parse and execution cost of all dashboard code before any single page became interactive.

On fast connections this was largely invisible. On slower mobile or corporate-proxied connections, the cumulative cost of ~93 KB of JavaScript across four pages created a noticeable delay before the UI responded.

What We Changed

Dynamic imports on heavy pages

The three heaviest pages now use next/dynamic to split their components into separate chunks:

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 is applied to the sanctions and settings pages. The matches page, at 18 KB, is a candidate for a future pass.

What this means in practice:

  • The browser only downloads a page's JavaScript when the user navigates to it.
  • While the chunk loads, a <PageSkeleton /> placeholder is shown immediately, so the layout is visible with no blank-screen flash.
  • Subsequent visits to the same page use the cached chunk.

Removed unused dependency

@tanstack/react-query was present in package.json but not used anywhere in the application. It has been removed. This eliminates its contribution to the bundle without any functional change.

Note for contributors: If React Query is needed in the future for client-side data fetching, re-add it at that point and wire it up with a QueryClientProvider at the appropriate layout level.

Pages Affected

PageApprox. sizeDynamic import added
Billing31 KB✅ Yes
Sanctions25 KB✅ Yes
Settings19 KB✅ Yes
Matches18 KB🔜 Planned

For Developers

When adding new dashboard pages, apply the same pattern if the page component is likely to exceed ~15 KB:

  1. Split the page's main content into a *-content.tsx file.
  2. In page.tsx, import it via next/dynamic with a <PageSkeleton /> fallback.
  3. Avoid importing large third-party libraries at the top level of page.tsx.