Skip to content

[FE-07] Add Suspense boundaries and lazy-load heavy dashboard components #275

Description

@Leothosine

Problem

QueryProvider is a client-only wrapper that forces the entire app to block on hydration before any content renders. No <Suspense> boundaries exist around heavy components (PopularItemsChart, RecentActivity, data tables). All admin pages are "use client" with no code splitting - all chart and table libraries are bundled into the initial JS payload even on pages that don't use them.

Proposed Solution

  1. Wrap PopularItemsChart and RecentActivity with Next.js dynamic() (ssr: false) to split them into separate chunks
  2. Add <Suspense fallback={<ChartSkeleton />}> around each dynamically imported chart
  3. Add <Suspense fallback={<TableSkeleton />}> around each admin data table section
  4. Restructure app/layout.tsx so the static navigation shell renders before QueryProvider hydrates
  5. Use useTransition for navigation-triggered data loads

Acceptance Criteria

  • Recharts library code appears in a separate JS chunk (verified via bundle analyzer)
  • Static navigation shell is visible before chart data loads
  • Chart components have matching skeleton fallbacks (not generic spinners)
  • Lighthouse performance score on the admin dashboard improves by at least 10 points
  • Disabling JavaScript renders a meaningful static shell (navigation and page title visible)

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions