Charting libraries (Recharts, Chart.js), code editors (Monaco), and rich-text editors routinely weigh 100–300KB gzipped each. Importing any of them statically means that weight lands in the initial bundle, inflating Time to Interactive for every page — including pages where the component never renders. ISO 25010:2011 time-behaviour captures the latency hit; the business impact is users abandoning a landing page because a chart used only on the analytics dashboard was eagerly loaded.
Medium because heavy UI components inflate the initial bundle and delay interactivity even on pages where those components are not displayed, though the impact is proportional to the library sizes involved.
Wrap any component over 50KB gzipped in a dynamic import with a loading fallback. In Next.js, use next/dynamic with ssr: false for browser-only libraries like canvas-based charts.
// components/analytics-chart.tsx
import dynamic from 'next/dynamic'
const LineChart = dynamic(
() => import('recharts').then((m) => m.LineChart),
{ ssr: false, loading: () => <Skeleton className="h-64 w-full" /> }
)
ID: performance-deep-dive.bundle-analysis.dynamic-imports-heavy-ui
Severity: medium
What to look for: Count all heavy UI library imports (charting, code editors, rich text editors, data tables over 50KB). Enumerate which use dynamic imports vs. static imports. Identify heavy UI libraries in the project (charting libraries like Recharts, data tables, modals, code editors). Check whether they use dynamic imports or are bundled eagerly. Look for React.lazy, import(), or framework-specific dynamic loading.
Pass criteria: Heavy UI components (charts, modals, code editors) are loaded on-demand via dynamic imports. They are not included in the initial bundle. At least 90% of heavy UI components (over 50KB each) should use dynamic imports.
Fail criteria: Heavy components like Recharts, Monaco Editor, or large modals are imported statically and included in the initial bundle, even if used only on certain pages or after user interaction.
Skip (N/A) when: The project does not contain heavy UI components, or all heavy components are rendered only after user interaction (e.g., a chart rendered on click).
Cross-reference: For bundle size impact of these heavy components, see the bundle-size-critical check.
Detail on fail: "Recharts library (125KB gzipped) imported statically and included in initial bundle. Chart rendered only on dashboard page, not on landing page" or "Monaco Editor bundled eagerly despite being used only in settings page"
Remediation: Use dynamic imports for heavy components that are not immediately visible.
// components/chart.tsx — dynamic import for heavy component
import dynamic from 'next/dynamic'
const Chart = dynamic(() => import('recharts').then(m => m.LineChart), { ssr: false })