| name | igniteui-react-optimize-bundle-size |
|---|---|
| description | Reduce bundle size in apps using Ignite UI for React — package selection, tree-shaking, and route-level code splitting of grids, charts, maps, and gauges. Use when the bundle or initial load is too large, when tree-shaking is not eliminating unused Ignite UI code, or when deciding what to lazy load. |
| user-invocable | true |
Standard React techniques (React.lazy + Suspense, route splitting, minification, compression, bundle analyzers) apply unchanged. This skill covers only what is specific to Ignite UI.
igniteui-react is published with "sideEffects": false and per-component modules, so named imports tree-shake well — a handful of core components costs little. The heavy families are separate packages:
| Package | Weight | Notes |
|---|---|---|
igniteui-react |
light per component | core UI; tree-shakes cleanly |
igniteui-grid-lite |
small | MIT grid; far lighter than the premium grids |
igniteui-react-grids |
heavy | Data/Tree/Pivot/Hierarchical grid |
igniteui-react-charts / -maps / -gauges |
heavy | legacy DV packages, weaker tree-shaking |
Two conclusions: install only the families you use, and split the heavy families out of the initial chunk. Downgrading IgrGrid to IgrGridLite is often the single largest win when the app only displays flat, read-only data — check the feature list in DATAVIZ.md first.
import { IgrButton, IgrCard } from 'igniteui-react'; // ✅ tree-shakes
import * as IgniteUI from 'igniteui-react'; // ❌ defeats tree-shaking
import { IgcButtonComponent } from 'igniteui-webcomponents'; // ❌ bypasses the wrapperNever import from igniteui-webcomponents (or igniteui-webcomponents-grids) directly. It pulls a second copy of the element definitions alongside the wrappers and skips the auto-registration the wrapper performs.
Lazy-load at the route or panel boundary, not the component. IgrGrid and the DV charts are only worth splitting when the whole view that uses them is deferred.
const Dashboard = lazy(() => import('./pages/Dashboard')); // grid + its theme CSS
const Analytics = lazy(() => import('./pages/Analytics')); // charts + registrationTwo Ignite-UI-specific details:
- Keep the grid theme CSS import inside the lazy chunk (
import 'igniteui-react-grids/grids/themes/light/bootstrap.css'inDashboard.tsx), so the grid stylesheet is not in the initial payload. The base theme CSS stays in the entry point — every page needs it. - Keep
.register()calls inside the lazy chunk too. Chart, gauge, and map modules must register at module scope of the file that uses them; hoisting the registration to the entry point pulls the whole DV package back into the initial bundle.
For manual chunking, give each family its own chunk so a page needing charts does not download grids:
// vite.config.ts
build: {
rollupOptions: {
output: {
manualChunks: {
'ig-core': ['igniteui-react'],
'ig-grids': ['igniteui-react-grids'], // only if actually installed
'ig-charts': ['igniteui-react-charts'], // only if actually installed
},
},
},
}# components referenced in JSX
grep -rhoE "<Igr[A-Za-z]+" src --include="*.tsx" | sort -u
# what is imported
grep -rn "from 'igniteui-react" src --include="*.tsx" --include="*.ts"Then run any bundle analyzer and check the initial chunk for igniteui-react-grids / -charts. If either appears there while only used on secondary routes, the split is not working — usually a shared module (a barrel index.ts, a types file, or a hoisted .register() call) re-imports it eagerly.
- A wildcard or barrel import somewhere in
src. - A local barrel file re-exporting Ignite UI components — it creates one module that depends on everything.
- CommonJS output: set
"module": "esnext"and"moduleResolution": "bundler"intsconfig.json. - Both
igniteui-react-gridsand@infragistics/igniteui-react-gridsresolved at once — pick one scope.
- igniteui-react-components — package routing and what each family provides
- grid-lite-to-igr-grid-migration — the reverse direction, when Grid Lite is not enough