com um clique
igniteui-wc-optimize-bundle-size
// Optimize application bundle size by importing only necessary components and using tree-shaking effectively
// Optimize application bundle size by importing only necessary components and using tree-shaking effectively
Identify and select the right Ignite UI Web Components for your app UI, then navigate to official docs, usage examples, and API references
Implement application views from design images using Ignite UI Web Components. Uses MCP servers (igniteui-cli, igniteui-theming) to discover components, generate themes, and follow best practices. Triggers when the user provides a design image (screenshot, mockup, wireframe) and wants it built as a working view with Ignite UI Web Components. Also triggers when the user asks to "implement this design", "build this UI", "convert this mockup", or "create a page from this image" in an Ignite UI Web Components project.
Integrate Ignite UI Web Components packages into React, Angular, Vue, or vanilla JS applications with framework-specific configurations
Customize Ignite UI Web Components styling using CSS custom properties, optional Sass, and the igniteui-theming MCP server for AI-assisted theming
Add a reactive property to an existing Lit web component with proper decorators, types, tests, and documentation
Create a new Lit web component following project conventions, including component class, styles, tests, Storybook story, and proper exports
| name | igniteui-wc-optimize-bundle-size |
| description | Optimize application bundle size by importing only necessary components and using tree-shaking effectively |
| user-invocable | true |
This skill helps users minimize their application's bundle size when using Ignite UI Web Components by importing only the components they need and following best practices for tree-shaking.
defineAllComponents()// DON'T DO THIS - imports ALL components (~500KB+)
import { defineAllComponents } from 'igniteui-webcomponents';
defineAllComponents();
Impact: Includes all 60+ components whether you use them or not.
// DO THIS - import only what you need
import {
defineComponents,
IgcButtonComponent,
IgcInputComponent,
IgcCardComponent
} from 'igniteui-webcomponents';
defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
Impact: Bundle includes only 3 components and their dependencies.
If you're using React, consider using the igniteui-react package instead of igniteui-webcomponents. It provides the same components with React-friendly wrappers and typically results in better tree-shaking:
npm install igniteui-react
import { IgrButton, IgrInput, IgrCard } from 'igniteui-react';
// No need to call defineComponents - components register automatically
function MyComponent() {
return (
<div>
<IgrButton variant="contained">Click me</IgrButton>
<IgrInput label="Name" />
<IgrCard>Content</IgrCard>
</div>
);
}
Benefits for bundle size:
For more details, see the igniteui-wc-integrate-with-framework skill.
Installation:
npm install --save-dev webpack-bundle-analyzer
Configuration (webpack.config.js):
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'bundle-report.html'
})
]
};
Run analysis:
npm run build
# Open bundle-report.html to see what's included
Installation:
npm install --save-dev rollup-plugin-visualizer
Configuration (vite.config.ts):
import { defineConfig } from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
})
]
});
Run analysis:
npm run build
# Opens stats.html automatically
Installation:
npm install --save-dev source-map-explorer
Package.json:
{
"scripts": {
"analyze": "source-map-explorer 'dist/**/*.js'"
}
}
Run:
npm run build
npm run analyze
Search your codebase for component usage:
# Search for component tags in templates
grep -r "igc-" src/ --include="*.html" --include="*.tsx" --include="*.vue"
# List unique components
grep -roh "igc-[a-z-]*" src/ | sort | uniq
Check what you're importing vs what you're using:
// Find in your code
import {
defineComponents,
IgcButtonComponent,
IgcInputComponent,
IgcCardComponent,
IgcSelectComponent, // ← Are you using this?
IgcComboComponent, // ← Are you using this?
} from 'igniteui-webcomponents';
Remove components you're not using:
// Before: 5 components imported
import {
defineComponents,
IgcButtonComponent,
IgcInputComponent,
IgcCardComponent,
IgcSelectComponent,
IgcComboComponent,
} from 'igniteui-webcomponents';
defineComponents(
IgcButtonComponent,
IgcInputComponent,
IgcCardComponent,
IgcSelectComponent,
IgcComboComponent
);
// After: Only 3 components needed
import {
defineComponents,
IgcButtonComponent,
IgcInputComponent,
IgcCardComponent,
} from 'igniteui-webcomponents';
defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
Load components only when needed to reduce initial bundle size.
// Load immediately (increases initial bundle)
import { defineComponents, IgcDialogComponent } from 'igniteui-webcomponents';
defineComponents(IgcDialogComponent);
// Lazy load (smaller initial bundle)
async function showDialog() {
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
defineComponents(IgcDialogComponent);
const dialog = document.createElement('igc-dialog');
// ... use dialog
}
import React, { lazy, Suspense, useState } from 'react';
// Lazy load the dialog component
const IgrDialog = lazy(() =>
import('igniteui-react').then(module => ({ default: module.IgrDialog }))
);
function MyComponent() {
const [showDialog, setShowDialog] = useState(false);
return (
<>
<button onClick={() => setShowDialog(true)}>Open Dialog</button>
{showDialog && (
<Suspense fallback={<div>Loading...</div>}>
<IgrDialog open>
<h2>Dialog Content</h2>
</IgrDialog>
</Suspense>
)}
</>
);
}
import React, { useState } from 'react';
// Lazy load component registration
const lazyLoadDialog = async () => {
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
defineComponents(IgcDialogComponent);
};
function MyComponent() {
const [dialogReady, setDialogReady] = useState(false);
const openDialog = async () => {
if (!dialogReady) {
await lazyLoadDialog();
setDialogReady(true);
}
// Show dialog
};
return (
<button onClick={openDialog}>Open Dialog</button>
);
}
<script setup lang="ts">
import { ref } from 'vue';
const dialogReady = ref(false);
async function openDialog() {
if (!dialogReady.value) {
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
defineComponents(IgcDialogComponent);
dialogReady.value = true;
}
// Show dialog
}
</script>
<template>
<button @click="openDialog">Open Dialog</button>
<igc-dialog v-if="dialogReady" open>
<h2>Dialog Content</h2>
</igc-dialog>
</template>
import { Component } from '@angular/core';
@Component({
selector: 'app-my-component',
template: `
<button (click)="openDialog()">Open Dialog</button>
<igc-dialog *ngIf="dialogReady" [open]="true">
<h2>Dialog Content</h2>
</igc-dialog>
`
})
export class MyComponent {
dialogReady = false;
async openDialog() {
if (!this.dialogReady) {
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
defineComponents(IgcDialogComponent);
this.dialogReady = true;
}
}
}
Load components only for specific routes.
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { lazy, Suspense } from 'react';
// Lazy load route components
const HomePage = lazy(() => import('./pages/Home'));
const DashboardPage = lazy(() => import('./pages/Dashboard'));
function App() {
return (
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/dashboard" element={<DashboardPage />} />
</Routes>
</Suspense>
</BrowserRouter>
);
}
In route component (pages/Dashboard.tsx):
import { IgrCard, IgrButton } from 'igniteui-react';
function Dashboard() {
return (
<div>
<IgrCard>
<h2>Dashboard</h2>
<p>Dashboard content here</p>
</IgrCard>
</div>
);
}
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/',
component: () => import('../views/Home.vue') // Lazy load
},
{
path: '/dashboard',
component: () => import('../views/Dashboard.vue') // Lazy load
}
];
export default createRouter({
history: createWebHistory(),
routes
});
In route component (views/Dashboard.vue):
<script setup lang="ts">
import { onMounted } from 'vue';
onMounted(async () => {
// Load components only for this route
const { defineComponents, IgcCardComponent } = await import('igniteui-webcomponents');
defineComponents(IgcCardComponent);
});
</script>
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
build: {
// Enable minification
minify: 'terser',
terserOptions: {
compress: {
drop_console: true, // Remove console.logs
drop_debugger: true
}
},
// Optimize chunk splitting
rollupOptions: {
output: {
manualChunks: {
// Separate vendor chunks
'vendor': ['igniteui-webcomponents'],
}
}
},
// Set chunk size warning limit
chunkSizeWarningLimit: 600,
},
// Optimize deps
optimizeDeps: {
include: ['igniteui-webcomponents']
}
});
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10,
},
igniteui: {
test: /[\\/]node_modules[\\/]igniteui-webcomponents[\\/]/,
name: 'igniteui',
priority: 20,
}
}
},
minimize: true,
},
// Tree shaking
mode: 'production',
};
Here's what you can expect in terms of bundle size:
| Import Strategy | Approximate Size (gzipped) | Components Included |
|---|---|---|
defineAllComponents() | ~500KB+ | All 60+ components |
10 components via defineComponents() | ~150-200KB | 10 components + deps |
5 components via defineComponents() | ~100-150KB | 5 components + deps |
3 components via defineComponents() | ~80-120KB | 3 components + deps |
1 component via defineComponents() | ~50-80KB | 1 component + deps |
Note: Sizes vary based on which components you import (some have more dependencies than others).
defineAllComponents() unless you truly need every componentdefineComponents() with specific components you needInvestigate:
igniteui-react instead of igniteui-webcomponentsSolutions:
// Review your imports - are you using all of these?
import {
defineComponents,
IgcButtonComponent,
IgcInputComponent,
IgcSelectComponent,
IgcComboComponent,
IgcDatePickerComponent
} from 'igniteui-webcomponents';
// Consider lazy loading components you don't need immediately
async function loadDialog() {
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
defineComponents(IgcDialogComponent);
}
Cause: Forgot to import a component you're using
Solution:
// Error: <igc-button> not working
// You're using igc-button but didn't import it
import { defineComponents, IgcButtonComponent } from 'igniteui-webcomponents';
defineComponents(IgcButtonComponent); // Add this
Solution: Update type imports:
// Import types separately if needed
import type { IgcButtonComponent } from 'igniteui-webcomponents';
Using bundlesize (for any build tool):
npm install --save-dev bundlesize
Package.json:
{
"scripts": {
"test:size": "bundlesize"
},
"bundlesize": [
{
"path": "./dist/**/*.js",
"maxSize": "300 kB"
}
]
}
Run in CI:
npm run build
npm run test:size
name: Bundle Size Check
on: [pull_request]
jobs:
size:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npm run build
- run: npm run test:size
After optimization, you should see: