| name | igniteui-react-optimize-bundle-size |
| description | This skill optimizes application bundle size when using Ignite UI for React and should be used when the bundle is too large, when setting up tree-shaking, or when lazy loading heavy components like grids and charts |
| user-invocable | true |
Optimize Bundle Size
This skill helps users minimize their React application's bundle size when using Ignite UI for React by importing only the components they need, leveraging tree-shaking, and applying lazy loading strategies.
Example Usage
- "My bundle size is too large"
- "How do I reduce the size of igniteui-react?"
- "Import only the components I need"
- "Tree-shake unused components"
- "Optimize imports for production"
- "How do I lazy load the data grid?"
Related Skills
When to Use
- Application bundle size is too large
- User wants to optimize for production
- User is importing more components than needed
- User asks about tree-shaking or optimization
- User wants to improve load times
- User wants to code-split heavy components like grids or charts
Key Principles
- Install only the packages you need — don't install
igniteui-react-grids if you only use core UI components
- Use named imports — enable tree-shaking by importing specific components
- Lazy load heavy components — use
React.lazy + Suspense for grids, charts, and other large components
- Analyze your bundle — use tools to identify what's being included
Granular Package Imports
Only install the packages you actually use:
| Package | Contains | Install only if you need… |
|---|
igniteui-react | Buttons, inputs, dialogs, calendars, lists, etc. | Core UI components |
igniteui-react + igniteui-grid-lite | Lightweight grid (IgrGridLite from igniteui-react/grid-lite) | Simple tabular data (MIT, requires both packages) |
igniteui-react-grids | DataGrid, TreeGrid, PivotGrid, HierarchicalGrid | Advanced data grids (commercial) |
igniteui-react-charts | Category, Pie, Financial, Scatter charts | Charts and data visualization (commercial) |
igniteui-react-maps | Geographic maps | Map visualizations (commercial) |
igniteui-react-gauges | Radial and linear gauges | Gauge indicators (commercial) |
npm install igniteui-react
npm install igniteui-react-grids
npm install igniteui-react-charts
Import Strategies
❌ Bad: Wildcard / Barrel Imports
import * as IgniteUI from 'igniteui-react';
function App() {
return <IgniteUI.IgrButton>Click</IgniteUI.IgrButton>;
}
Impact: Tree-shaking cannot eliminate unused components.
✅ Good: Named Imports
import { IgrButton, IgrInput, IgrCard } from 'igniteui-react';
function App() {
return (
<div>
<IgrInput label="Name" />
<IgrButton><span>Submit</span></IgrButton>
<IgrCard>Content</IgrCard>
</div>
);
}
Impact: Bundle includes only the three components and their dependencies. Tree-shaking removes everything else.
Lazy Loading with React.lazy + Suspense
Code-split heavy components behind lazy imports to reduce initial bundle size.
Lazy Loading a Single Component
import { lazy, Suspense, useState } from 'react';
const IgrDialog = lazy(() =>
import('igniteui-react').then(module => ({ default: module.IgrDialog }))
);
function App() {
const [showDialog, setShowDialog] = useState(false);
return (
<>
<button onClick={() => setShowDialog(true)}>Open Dialog</button>
{showDialog && (
<Suspense fallback={<div>Loading...</div>}>
<IgrDialog open title="Hello">
<p>Lazy loaded dialog content</p>
</IgrDialog>
</Suspense>
)}
</>
);
}
Lazy Loading a Heavy Page Component
This is the recommended approach for code-splitting: wrap entire page components that use heavy Ignite UI components.
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { lazy, Suspense } from 'react';
const HomePage = lazy(() => import('./pages/Home'));
const DashboardPage = lazy(() => import('./pages/Dashboard'));
const AnalyticsPage = lazy(() => import('./pages/Analytics'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/dashboard" element={<DashboardPage />} />
<Route path="/analytics" element={<AnalyticsPage />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
import { IgrGrid, IgrColumn } from 'igniteui-react-grids';
import 'igniteui-react-grids/grids/themes/light/bootstrap.css';
export default function Dashboard() {
return (
<IgrGrid data={data} autoGenerate={false}>
<IgrColumn field="name" header="Name" />
<IgrColumn field="value" header="Value" />
</IgrGrid>
);
}
import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts';
IgrCategoryChartModule.register();
export default function Analytics() {
return <IgrCategoryChart dataSource={data} width="100%" height="500px" />;
}
Result: The grid and chart bundles are only downloaded when the user navigates to those routes.
Analyzing Your Bundle
Using Vite's Rollup Visualizer
npm install --save-dev rollup-plugin-visualizer
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
react(),
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
})
]
});
npm run build
Using Webpack Bundle Analyzer
npm install --save-dev webpack-bundle-analyzer
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'bundle-report.html'
})
]
};
Using source-map-explorer
npm install --save-dev source-map-explorer
{
"scripts": {
"analyze": "source-map-explorer 'dist/**/*.js'"
}
}
npm run build
npm run analyze
What to look for: Check if igniteui-react-grids or igniteui-react-charts appear in the initial bundle even though they're only used on specific routes.
Audit Your Component Usage
1. Find What Components You're Actually Using
grep -roh "Igr[A-Z][a-zA-Z]*" src/ --include="*.tsx" --include="*.ts" | sort | uniq
2. Compare with Your Imports
grep -r "from 'igniteui-react" src/ --include="*.tsx" --include="*.ts"
3. Remove Unused Imports
import { IgrButton, IgrInput, IgrCard, IgrSelect, IgrCombo } from 'igniteui-react';
import { IgrButton, IgrInput, IgrCard } from 'igniteui-react';
Build Configuration Optimizations
Vite Configuration
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: {
manualChunks: {
'igniteui-core': ['igniteui-react'],
}
}
},
chunkSizeWarningLimit: 600,
},
optimizeDeps: {
include: ['igniteui-react']
}
});
Webpack Configuration
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
igniteui: {
test: /[\\/]node_modules[\\/]igniteui-react[\\/]/,
name: 'igniteui',
priority: 20,
},
igniteuiGrids: {
test: /[\\/]node_modules[\\/]igniteui-react-grids[\\/]/,
name: 'igniteui-grids',
priority: 20,
}
}
},
minimize: true,
},
mode: 'production',
};
Best Practices Checklist
Common Issues & Solutions
Issue: Bundle still large after using named imports
Investigate:
- Check if you're importing from
igniteui-webcomponents instead of igniteui-react
- Verify tree-shaking is working (check build output with a bundle analyzer)
- Look for barrel imports (
import * as)
- Check if large packages like
igniteui-react-grids are in the initial bundle instead of being lazy loaded
Issue: Lazy loaded component flashes or shows fallback too long
Solution: Preload the component on hover or route prefetch:
const DashboardPage = lazy(() => import('./pages/Dashboard'));
function NavLink() {
const preload = () => { import('./pages/Dashboard'); };
return <a href="/dashboard" onMouseEnter={preload}>Dashboard</a>;
}
Issue: Tree-shaking not working
Cause: Using require() instead of import, or a build tool that doesn't support ES module tree-shaking.
Solution: Ensure your project uses ES modules:
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler"
}
}
Expected Results
After optimization, you should see:
- Initial load time reduced by 40–60%
- Bundle size reduced by 50–80% (compared to importing everything)
- Better Core Web Vitals scores
- Faster time to interactive
- Lower bandwidth usage for users
Additional Resources