Skip to content

perf: reduce initial bundle size by 93% through code splitting and dependency cleanup#419

Open
YagUber wants to merge 8 commits intocedya77:devfrom
YagUber:perf/bundle-optimization
Open

perf: reduce initial bundle size by 93% through code splitting and dependency cleanup#419
YagUber wants to merge 8 commits intocedya77:devfrom
YagUber:perf/bundle-optimization

Conversation

@YagUber
Copy link
Copy Markdown
Contributor

@YagUber YagUber commented Apr 11, 2026

Summary

Significant bundle size and build time improvements through lazy loading, dependency cleanup, and proper code splitting.

Changes

Bundle Size

  • Initial bundle (93% reduction)
    • 630kB to 51kB gzipped
    • 2,364kB to 163kB raw

Dependency Changes

  • Replaced @tremor/react with native Recharts components, eliminating duplicate bundling of Recharts, Headless UI, and floating-ui
  • Removed unused lovable-tagger dev dependency
    • If you are still using Lovable it should be gated behind development
  • Upgraded Vite 5 to 8 and migrated to @vitejs/plugin-react (now uses OXC transformer by default)
    • Build time goes from 7s to 1s from this alone

Code Splitting

  • Lazy load Dashboard and RatingPage routes (gated behind window flags)
  • Extract all 7 dashboard tab components into separate files
  • Lazy load all settings sections and catalog integration dialogs
  • Fixed settingsPages array to store component references instead of JSX instances to allow proper tree shaking

Build Config

  • Rename postcss.config.js to postcss.config.mjs to avoid ESM reparse warning on every build
  • Production builds now use hash only chunk filenames

YagUber added 8 commits April 10, 2026 17:45
Vite 8 uses OXC transformer by default via @vitejs/plugin-react, replacing the SWC-based plugin. Build time reduced from 7s to 1s.
Node was reparsing postcss.config.js as an ES module on every build due to ESM syntax being detected without an explicit module type.

Renaming to .mjs makes the module type explicit and eliminates the performance overhead warning. Cannot use "type": "module" in package.json as this breaks the CommonJS backend build.
If the maintainer (cedya77) still actively uses Lovable, this could and should be gated in vite.config.ts instead.
All settings tab components and catalog integration dialogs were statically imported, bundling everything into the initial load.

Additionally Dashboard and RatingPage were statically imported in SettingsLayout despite being gated behind window.DASHBOARD_MODE and window.RATING_MODE flags.

- Converted to React.lazy so each section and dialog only loads when first opened.
- Also fixed settingsPages array to store component references instead of JSX instances.
Tremor was pulling in its own bundled copy of Recharts, Headless UI, and floating-ui, resulting in these libraries being shipped twice.

- Replaced AreaChart and BarList with native Recharts equivalents and plain JSX respectively.
All dashboard tab components (Overview, Analytics, Content, Performance, System, Operations, Users) were defined in a single Dashboard.tsx file, preventing code splitting.

- Extracted each into its own file and lazy loaded them.
In development builds, Rollup(down) includes the module name in chunk filenames for easier debugging. Production builds now use hash only filenames to avoid including internal module/component names in the shipped assets.
@YagUber
Copy link
Copy Markdown
Contributor Author

YagUber commented Apr 11, 2026

Let me know if this is something you are interested in, and I will rebase. If you are, #418 should go first since it fixes some dashboard theming issues that need to be moved to their respective extracted files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant