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:
- The browser received an empty shell of the page.
- A loading spinner was shown while the component mounted and fired the data request.
- 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
| Behaviour | Before | After |
|---|---|---|
| Initial page render | Loading spinner | Populated content immediately |
| JavaScript sent to browser | Full page + data-fetching logic | Interactive elements only |
| Time to Interactive | Delayed (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
useEffectdata-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
PeopleListClientcomponent (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.