All Docs
FeaturesCalmony Sanctions MonitorUpdated March 12, 2026

Faster Dashboards with React Server Components

Faster Dashboards with React Server Components

Released in v0.1.94

Background

Prior to this release, the heaviest pages in the compliance dashboard — People, Matches, and Billing — were client components marked with 'use client'. Each page fetched its data inside a useEffect hook, which meant:

  1. The browser received an empty shell of the page.
  2. A loading spinner was shown while the component mounted and fired the data request.
  3. The populated page appeared only after the round-trip to the API completed.

This pattern also sent unnecessary data-fetching code to the browser as part of the JavaScript bundle.

What changed in PERF-14

These pages have been refactored to use React Server Components (RSC). Under the new architecture:

  • The page shell is a Server Component. It fetches the required data directly on the server (e.g. the people list, sanctions matches, billing records) before any HTML is sent to the browser.
  • Interactive elements — search bars, filter dropdowns, pagination controls, and action buttons — are extracted into dedicated client components (e.g. PeopleListClient). These are the only parts that ship JavaScript to the browser.
// Before (simplified)
'use client';
export default function PeoplePage() {
  const [people, setPeople] = useState([]);
  useEffect(() => { fetchPeople().then(setPeople); }, []);
  return people.length ? <PeopleList data={people} /> : <Spinner />;
}

// After (simplified)
// people/page.tsx — Server Component (no 'use client' directive)
export default async function PeoplePage() {
  const people = await fetchPeople(); // runs on the server
  return <PeopleListClient initialData={people} />;
}

User-facing improvements

BehaviourBeforeAfter
Initial page renderLoading spinnerPopulated content immediately
JavaScript sent to browserFull page + data-fetching logicInteractive elements only
Time to InteractiveDelayed (two round-trips)Faster (data arrives with HTML)

Affected pages

  • Dashboard → People (/dashboard/people)
  • Dashboard → Matches (/dashboard/matches)
  • Dashboard → Billing (/dashboard/billing)

Notes for developers

  • If you have extended any of these pages with custom useEffect data-fetching, migrate that logic into the Server Component layer or into a dedicated server action.
  • Client-only state (e.g. selected filter values, open/closed modals) still lives in the extracted client components and is unaffected.
  • The PeopleListClient component (and equivalent components for Matches and Billing) accept initial data as props and can refetch client-side as needed for interactive operations such as search and pagination.