Skip to main content
All Docs
FeaturesBlockManOSUpdated March 26, 2026

Reducing JavaScript Bundle Size in the Dashboard

Reducing JavaScript Bundle Size in the Dashboard

Release: v1.0.56 · Control: PERF-05 · Category: Frontend Performance

Background

The Blockboss dashboard is composed of a number of large, feature-rich client components — each covering a distinct area of block management such as budgeting, bank reconciliation, GDPR compliance, Irish legislation references, sinking funds, planned preventative maintenance (PPM), and general maintenance.

Before code splitting was applied, every one of these modules was included in a single monolithic JavaScript bundle that was downloaded by the browser on the very first page load — regardless of which section of the dashboard the user actually navigated to.

The Problem

The combined uncompressed source size of the primary dashboard client components exceeded 700 KB:

ComponentSource Size
budget/client.tsx72 KB
irish-legislation/client.tsx66 KB
gdpr/client.tsx64 KB
bank-reconciliation/client.tsx62 KB
sinking-fund/client.tsx58 KB
ppm/client.tsx54 KB
maintenance/client.tsx53 KB

This created an unnecessarily large initial JavaScript payload, increasing parse and execution time and delaying when the dashboard became interactive for users — particularly on slower connections or lower-powered devices.

Solution

1. Dynamic Imports via PERF-01

The primary resolution for PERF-05 is the application of dynamic imports across all large dashboard client components. This work was introduced as part of PERF-01 (code splitting) and ensures that each module's JavaScript is only fetched from the network when the user navigates to that section of the dashboard.

For example, instead of eagerly importing the budget module at startup:

// Before — eagerly loaded, always in the bundle
import BudgetClient from './budget/client';

It is loaded dynamically when needed:

// After — loaded on demand via dynamic import
const BudgetClient = dynamic(() => import('./budget/client'), {
  loading: () => <LoadingSpinner />,
});

This pattern is applied consistently across all large dashboard client components.

2. Lazy-Loaded Sub-Components

Beyond route-level code splitting, an internal audit of the largest client components identified UI panels that are only ever rendered in response to a specific user interaction (opening a detail view, clicking a record, etc.). These are ideal candidates for an additional layer of lazy loading:

service-charges/arrears-detail-panel.tsx (32 KB)

This panel is only displayed when a property manager drills into an individual arrears record. Since it is never visible on initial render, its 32 KB of JavaScript does not need to be included in the parent component's chunk.

budget-detail-panel.tsx (41 KB)

This panel is only displayed when a user opens a specific budget entry for detailed review. At 41 KB, deferring its load until the panel is opened provides a meaningful reduction in the initial chunk size for the budget module.

These sub-components are extracted and loaded lazily, typically using a pattern like:

const ArrearsDetailPanel = dynamic(
  () => import('./arrears-detail-panel'),
  { ssr: false }
);

Performance Impact

MetricEffect
Initial JS payloadSignificantly reduced — modules load on demand
Time to Interactive (TTI)Improved — less JS to parse and execute on load
Largest Contentful Paint (LCP)Improved — browser is not blocked by unused module code
Sub-component payloadsDeferred until user interaction (modals, detail panels)

Affected Files

  • src/app/dashboard/budget/client.tsx
  • src/app/dashboard/bank-reconciliation/client.tsx
  • src/app/dashboard/gdpr/client.tsx
  • src/app/dashboard/irish-legislation/client.tsx
  • src/app/dashboard/sinking-fund/client.tsx
  • src/app/dashboard/ppm/client.tsx
  • src/app/dashboard/maintenance/client.tsx
  • src/app/dashboard/service-charges/arrears-detail-panel.tsx
  • src/app/dashboard/budget/budget-detail-panel.tsx

Related

  • PERF-01 — Dynamic imports / route-level code splitting (prerequisite for this fix)
  • PERF-05 — JavaScript bundle size control (this release)