π Description
The dashboard (app/dashboard/page.tsx) renders many widgets eagerly β components/Dashboard/MoneyDistributionWidget.tsx, components/Dashboard/SixMonthTrendsWidget.tsx, components/Dashboard/SavingsByGoalWidget.tsx, components/Dashboard/RecentTransactionsWidget.tsx, and the split widget components/CurrentMoneySplitWidget.tsx. The chart widgets pull in Recharts (heavy) and re-render on every parent state change. There's a separate open issue for the Insights charts; this targets the dashboard widgets specifically.
This issue lazy-loads the chart widgets and memoizes the static ones to reduce the dashboard's initial bundle and re-render churn.
Why this matters: the dashboard is the most-visited authenticated screen. Eagerly importing Recharts for every widget inflates the first load and makes unrelated state changes repaint charts. Lazy + memo is a measurable, low-risk win.
π― Requirements & Context
Functional requirements
Context & constraints
- Don't change widget APIs unnecessarily β this is a perf refactor.
- Capture a before/after measurement (bundle delta and/or render count) in the PR.
π οΈ Suggested Execution
1. Fork & branch
git checkout -b perf/dashboard-widget-lazy-memo
2. Implement changes
- Convert chart widgets to dynamic imports with skeleton fallbacks.
- Memoize static widgets and stabilize props.
- Document the perf approach + measurements in
docs/.
- Edge cases: reduced-motion skeletons, no layout shift, error fallback still works (WidgetErrorState), responsive, SSR/CSR boundaries respected.
3. Test & commit
npm run build
npm run lint
npx tsc --noEmit
npm run test:coverage
Example commit message
perf(dashboard): lazy-load chart widgets and memoize static ones
Defers Recharts-backed widgets behind dynamic imports with skeleton fallbacks
and memoizes pure widgets to cut initial load and re-render churn.
β
Acceptance Criteria & Guidelines
| Requirement |
Target |
| Chart widgets lazy-loaded with skeletons |
Required |
| Before/after measurement in PR |
Required |
| No layout shift on resolve |
Required |
| Behavior parity (no regressions) |
Required |
| Responsive + reduced-motion |
Required |
build + lint + tsc --noEmit clean |
Required |
| Timeframe |
96 hours from assignment |
π¬ Community & Support
Questions and design discussion β join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Comment to claim. π
π Description
The dashboard (
app/dashboard/page.tsx) renders many widgets eagerly βcomponents/Dashboard/MoneyDistributionWidget.tsx,components/Dashboard/SixMonthTrendsWidget.tsx,components/Dashboard/SavingsByGoalWidget.tsx,components/Dashboard/RecentTransactionsWidget.tsx, and the split widgetcomponents/CurrentMoneySplitWidget.tsx. The chart widgets pull in Recharts (heavy) and re-render on every parent state change. There's a separate open issue for the Insights charts; this targets the dashboard widgets specifically.This issue lazy-loads the chart widgets and memoizes the static ones to reduce the dashboard's initial bundle and re-render churn.
π― Requirements & Context
Functional requirements
next/dynamicorReact.lazy+ Suspense) with skeleton fallbacks fromcomponents/ui/LoadingSkeletons.tsx.React.memoand stabilize props withuseMemo/useCallbackwhere the parent re-renders frequently.Context & constraints
π οΈ Suggested Execution
1. Fork & branch
2. Implement changes
docs/.3. Test & commit
Example commit message
β Acceptance Criteria & Guidelines
build+lint+tsc --noEmitclean㪠Community & Support
Questions and design discussion β join the RemitWise contributor community on Discord: https://discord.gg/CtQuPZFMA
Comment to claim. π