igniteui-cli 14.10.0-alpha.2 → 14.10.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/templates/react/igr-ts/projects/_base/files/__dot__vscode/mcp.json +2 -2
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-choose-components/SKILL.md +358 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-customize-component-theme/SKILL.md +615 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-integrate-with-framework/SKILL.md +112 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-integrate-with-framework/references/angular.md +185 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-integrate-with-framework/references/react.md +116 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-integrate-with-framework/references/vanilla-js.md +118 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-integrate-with-framework/references/vue.md +181 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__claude/skills/igniteui-wc-optimize-bundle-size/SKILL.md +709 -0
- package/templates/webcomponents/igc-ts/projects/_base/files/__dot__vscode/mcp.json +2 -2
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: igniteui-wc-optimize-bundle-size
|
|
3
|
+
description: Optimize application bundle size by importing only necessary components and using tree-shaking effectively
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Optimize Bundle Size
|
|
8
|
+
|
|
9
|
+
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.
|
|
10
|
+
|
|
11
|
+
## Example Usage
|
|
12
|
+
|
|
13
|
+
- "My bundle size is too large"
|
|
14
|
+
- "How do I reduce the size of igniteui-webcomponents?"
|
|
15
|
+
- "Import only the components I need"
|
|
16
|
+
- "Tree-shake unused components"
|
|
17
|
+
- "Optimize imports for production"
|
|
18
|
+
|
|
19
|
+
## Related Skills
|
|
20
|
+
|
|
21
|
+
- [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) - Proper integration setup
|
|
22
|
+
- [igniteui-wc-customize-component-theme](../igniteui-wc-customize-component-theme/SKILL.md) - Theming after optimization
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- User's bundle size is too large
|
|
27
|
+
- User wants to optimize for production
|
|
28
|
+
- User is importing more components than needed
|
|
29
|
+
- User asks about tree-shaking or optimization
|
|
30
|
+
- User wants to improve load times
|
|
31
|
+
|
|
32
|
+
## Key Principles
|
|
33
|
+
|
|
34
|
+
1. **Import only what you use** - Don't use `defineAllComponents()`
|
|
35
|
+
2. **Use named imports** - Enable tree-shaking
|
|
36
|
+
3. **Analyze your bundle** - Identify what's being included
|
|
37
|
+
4. **Lazy load when possible** - Load components on demand
|
|
38
|
+
|
|
39
|
+
## Import Strategies
|
|
40
|
+
|
|
41
|
+
### ❌ Bad: Import Everything
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// DON'T DO THIS - imports ALL components (~500KB+)
|
|
45
|
+
import { defineAllComponents } from 'igniteui-webcomponents';
|
|
46
|
+
|
|
47
|
+
defineAllComponents();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Impact:** Includes all 60+ components whether you use them or not.
|
|
51
|
+
|
|
52
|
+
### ✅ Good: Import Specific Components
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// DO THIS - import only what you need
|
|
56
|
+
import {
|
|
57
|
+
defineComponents,
|
|
58
|
+
IgcButtonComponent,
|
|
59
|
+
IgcInputComponent,
|
|
60
|
+
IgcCardComponent
|
|
61
|
+
} from 'igniteui-webcomponents';
|
|
62
|
+
|
|
63
|
+
defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Impact:** Bundle includes only 3 components and their dependencies.
|
|
67
|
+
|
|
68
|
+
## React Applications
|
|
69
|
+
|
|
70
|
+
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:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install igniteui-react
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { IgrButton, IgrInput, IgrCard } from 'igniteui-react';
|
|
78
|
+
|
|
79
|
+
// No need to call defineComponents - components register automatically
|
|
80
|
+
function MyComponent() {
|
|
81
|
+
return (
|
|
82
|
+
<div>
|
|
83
|
+
<IgrButton variant="contained">Click me</IgrButton>
|
|
84
|
+
<IgrInput label="Name" />
|
|
85
|
+
<IgrCard>Content</IgrCard>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Benefits for bundle size:**
|
|
92
|
+
- Automatic tree-shaking (only imported components are included)
|
|
93
|
+
- No need for component registration overhead
|
|
94
|
+
- Better integration with React build tools
|
|
95
|
+
|
|
96
|
+
For more details, see the [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) skill.
|
|
97
|
+
|
|
98
|
+
## Analyzing Your Bundle
|
|
99
|
+
|
|
100
|
+
### Using Webpack Bundle Analyzer
|
|
101
|
+
|
|
102
|
+
**Installation:**
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npm install --save-dev webpack-bundle-analyzer
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Configuration (`webpack.config.js`):**
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
plugins: [
|
|
115
|
+
new BundleAnalyzerPlugin({
|
|
116
|
+
analyzerMode: 'static',
|
|
117
|
+
openAnalyzer: false,
|
|
118
|
+
reportFilename: 'bundle-report.html'
|
|
119
|
+
})
|
|
120
|
+
]
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Run analysis:**
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm run build
|
|
128
|
+
# Open bundle-report.html to see what's included
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Using Vite Bundle Analyzer
|
|
132
|
+
|
|
133
|
+
**Installation:**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm install --save-dev rollup-plugin-visualizer
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Configuration (`vite.config.ts`):**
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { defineConfig } from 'vite';
|
|
143
|
+
import { visualizer } from 'rollup-plugin-visualizer';
|
|
144
|
+
|
|
145
|
+
export default defineConfig({
|
|
146
|
+
plugins: [
|
|
147
|
+
visualizer({
|
|
148
|
+
open: true,
|
|
149
|
+
gzipSize: true,
|
|
150
|
+
brotliSize: true,
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Run analysis:**
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npm run build
|
|
160
|
+
# Opens stats.html automatically
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Using source-map-explorer
|
|
164
|
+
|
|
165
|
+
**Installation:**
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npm install --save-dev source-map-explorer
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Package.json:**
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"scripts": {
|
|
176
|
+
"analyze": "source-map-explorer 'dist/**/*.js'"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Run:**
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npm run build
|
|
185
|
+
npm run analyze
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Audit Your Component Usage
|
|
189
|
+
|
|
190
|
+
### 1. Find What Components You're Actually Using
|
|
191
|
+
|
|
192
|
+
Search your codebase for component usage:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Search for component tags in templates
|
|
196
|
+
grep -r "igc-" src/ --include="*.html" --include="*.tsx" --include="*.vue"
|
|
197
|
+
|
|
198
|
+
# List unique components
|
|
199
|
+
grep -roh "igc-[a-z-]*" src/ | sort | uniq
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 2. Compare with Your Imports
|
|
203
|
+
|
|
204
|
+
Check what you're importing vs what you're using:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Find in your code
|
|
208
|
+
import {
|
|
209
|
+
defineComponents,
|
|
210
|
+
IgcButtonComponent,
|
|
211
|
+
IgcInputComponent,
|
|
212
|
+
IgcCardComponent,
|
|
213
|
+
IgcSelectComponent, // ← Are you using this?
|
|
214
|
+
IgcComboComponent, // ← Are you using this?
|
|
215
|
+
} from 'igniteui-webcomponents';
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 3. Remove Unused Imports
|
|
219
|
+
|
|
220
|
+
Remove components you're not using:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Before: 5 components imported
|
|
224
|
+
import {
|
|
225
|
+
defineComponents,
|
|
226
|
+
IgcButtonComponent,
|
|
227
|
+
IgcInputComponent,
|
|
228
|
+
IgcCardComponent,
|
|
229
|
+
IgcSelectComponent,
|
|
230
|
+
IgcComboComponent,
|
|
231
|
+
} from 'igniteui-webcomponents';
|
|
232
|
+
|
|
233
|
+
defineComponents(
|
|
234
|
+
IgcButtonComponent,
|
|
235
|
+
IgcInputComponent,
|
|
236
|
+
IgcCardComponent,
|
|
237
|
+
IgcSelectComponent,
|
|
238
|
+
IgcComboComponent
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// After: Only 3 components needed
|
|
242
|
+
import {
|
|
243
|
+
defineComponents,
|
|
244
|
+
IgcButtonComponent,
|
|
245
|
+
IgcInputComponent,
|
|
246
|
+
IgcCardComponent,
|
|
247
|
+
} from 'igniteui-webcomponents';
|
|
248
|
+
|
|
249
|
+
defineComponents(IgcButtonComponent, IgcInputComponent, IgcCardComponent);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Lazy Loading Components
|
|
253
|
+
|
|
254
|
+
Load components only when needed to reduce initial bundle size.
|
|
255
|
+
|
|
256
|
+
### Vanilla JavaScript / TypeScript
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// Load immediately (increases initial bundle)
|
|
260
|
+
import { defineComponents, IgcDialogComponent } from 'igniteui-webcomponents';
|
|
261
|
+
defineComponents(IgcDialogComponent);
|
|
262
|
+
|
|
263
|
+
// Lazy load (smaller initial bundle)
|
|
264
|
+
async function showDialog() {
|
|
265
|
+
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
|
|
266
|
+
defineComponents(IgcDialogComponent);
|
|
267
|
+
|
|
268
|
+
const dialog = document.createElement('igc-dialog');
|
|
269
|
+
// ... use dialog
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### React (using igniteui-react)
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import React, { lazy, Suspense, useState } from 'react';
|
|
277
|
+
|
|
278
|
+
// Lazy load the dialog component
|
|
279
|
+
const IgrDialog = lazy(() =>
|
|
280
|
+
import('igniteui-react').then(module => ({ default: module.IgrDialog }))
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
function MyComponent() {
|
|
284
|
+
const [showDialog, setShowDialog] = useState(false);
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<>
|
|
288
|
+
<button onClick={() => setShowDialog(true)}>Open Dialog</button>
|
|
289
|
+
{showDialog && (
|
|
290
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
291
|
+
<IgrDialog open>
|
|
292
|
+
<h2>Dialog Content</h2>
|
|
293
|
+
</IgrDialog>
|
|
294
|
+
</Suspense>
|
|
295
|
+
)}
|
|
296
|
+
</>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### React (using web components directly)
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
import React, { useState } from 'react';
|
|
305
|
+
|
|
306
|
+
// Lazy load component registration
|
|
307
|
+
const lazyLoadDialog = async () => {
|
|
308
|
+
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
|
|
309
|
+
defineComponents(IgcDialogComponent);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
function MyComponent() {
|
|
313
|
+
const [dialogReady, setDialogReady] = useState(false);
|
|
314
|
+
|
|
315
|
+
const openDialog = async () => {
|
|
316
|
+
if (!dialogReady) {
|
|
317
|
+
await lazyLoadDialog();
|
|
318
|
+
setDialogReady(true);
|
|
319
|
+
}
|
|
320
|
+
// Show dialog
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<button onClick={openDialog}>Open Dialog</button>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Vue 3
|
|
330
|
+
|
|
331
|
+
```vue
|
|
332
|
+
<script setup lang="ts">
|
|
333
|
+
import { ref } from 'vue';
|
|
334
|
+
|
|
335
|
+
const dialogReady = ref(false);
|
|
336
|
+
|
|
337
|
+
async function openDialog() {
|
|
338
|
+
if (!dialogReady.value) {
|
|
339
|
+
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
|
|
340
|
+
defineComponents(IgcDialogComponent);
|
|
341
|
+
dialogReady.value = true;
|
|
342
|
+
}
|
|
343
|
+
// Show dialog
|
|
344
|
+
}
|
|
345
|
+
</script>
|
|
346
|
+
|
|
347
|
+
<template>
|
|
348
|
+
<button @click="openDialog">Open Dialog</button>
|
|
349
|
+
<igc-dialog v-if="dialogReady" open>
|
|
350
|
+
<h2>Dialog Content</h2>
|
|
351
|
+
</igc-dialog>
|
|
352
|
+
</template>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Angular
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { Component } from '@angular/core';
|
|
359
|
+
|
|
360
|
+
@Component({
|
|
361
|
+
selector: 'app-my-component',
|
|
362
|
+
template: `
|
|
363
|
+
<button (click)="openDialog()">Open Dialog</button>
|
|
364
|
+
<igc-dialog *ngIf="dialogReady" [open]="true">
|
|
365
|
+
<h2>Dialog Content</h2>
|
|
366
|
+
</igc-dialog>
|
|
367
|
+
`
|
|
368
|
+
})
|
|
369
|
+
export class MyComponent {
|
|
370
|
+
dialogReady = false;
|
|
371
|
+
|
|
372
|
+
async openDialog() {
|
|
373
|
+
if (!this.dialogReady) {
|
|
374
|
+
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
|
|
375
|
+
defineComponents(IgcDialogComponent);
|
|
376
|
+
this.dialogReady = true;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Route-Based Code Splitting
|
|
383
|
+
|
|
384
|
+
Load components only for specific routes.
|
|
385
|
+
|
|
386
|
+
### React Router
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
390
|
+
import { lazy, Suspense } from 'react';
|
|
391
|
+
|
|
392
|
+
// Lazy load route components
|
|
393
|
+
const HomePage = lazy(() => import('./pages/Home'));
|
|
394
|
+
const DashboardPage = lazy(() => import('./pages/Dashboard'));
|
|
395
|
+
|
|
396
|
+
function App() {
|
|
397
|
+
return (
|
|
398
|
+
<BrowserRouter>
|
|
399
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
400
|
+
<Routes>
|
|
401
|
+
<Route path="/" element={<HomePage />} />
|
|
402
|
+
<Route path="/dashboard" element={<DashboardPage />} />
|
|
403
|
+
</Routes>
|
|
404
|
+
</Suspense>
|
|
405
|
+
</BrowserRouter>
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**In route component (`pages/Dashboard.tsx`):**
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
import { IgrCard, IgrButton } from 'igniteui-react';
|
|
414
|
+
|
|
415
|
+
function Dashboard() {
|
|
416
|
+
return (
|
|
417
|
+
<div>
|
|
418
|
+
<IgrCard>
|
|
419
|
+
<h2>Dashboard</h2>
|
|
420
|
+
<p>Dashboard content here</p>
|
|
421
|
+
</IgrCard>
|
|
422
|
+
</div>
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Vue Router
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
// router/index.ts
|
|
431
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
432
|
+
|
|
433
|
+
const routes = [
|
|
434
|
+
{
|
|
435
|
+
path: '/',
|
|
436
|
+
component: () => import('../views/Home.vue') // Lazy load
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
path: '/dashboard',
|
|
440
|
+
component: () => import('../views/Dashboard.vue') // Lazy load
|
|
441
|
+
}
|
|
442
|
+
];
|
|
443
|
+
|
|
444
|
+
export default createRouter({
|
|
445
|
+
history: createWebHistory(),
|
|
446
|
+
routes
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**In route component (`views/Dashboard.vue`):**
|
|
451
|
+
|
|
452
|
+
```vue
|
|
453
|
+
<script setup lang="ts">
|
|
454
|
+
import { onMounted } from 'vue';
|
|
455
|
+
|
|
456
|
+
onMounted(async () => {
|
|
457
|
+
// Load components only for this route
|
|
458
|
+
const { defineComponents, IgcCardComponent } = await import('igniteui-webcomponents');
|
|
459
|
+
defineComponents(IgcCardComponent);
|
|
460
|
+
});
|
|
461
|
+
</script>
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Angular
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
// app-routing.module.ts
|
|
468
|
+
import { NgModule } from '@angular/core';
|
|
469
|
+
import { RouterModule, Routes } from '@angular/router';
|
|
470
|
+
|
|
471
|
+
const routes: Routes = [
|
|
472
|
+
{
|
|
473
|
+
path: 'dashboard',
|
|
474
|
+
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)
|
|
475
|
+
}
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
@NgModule({
|
|
479
|
+
imports: [RouterModule.forRoot(routes)],
|
|
480
|
+
exports: [RouterModule]
|
|
481
|
+
})
|
|
482
|
+
export class AppRoutingModule {}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Build Configuration Optimizations
|
|
486
|
+
|
|
487
|
+
### Vite Configuration
|
|
488
|
+
|
|
489
|
+
```typescript
|
|
490
|
+
// vite.config.ts
|
|
491
|
+
import { defineConfig } from 'vite';
|
|
492
|
+
|
|
493
|
+
export default defineConfig({
|
|
494
|
+
build: {
|
|
495
|
+
// Enable minification
|
|
496
|
+
minify: 'terser',
|
|
497
|
+
terserOptions: {
|
|
498
|
+
compress: {
|
|
499
|
+
drop_console: true, // Remove console.logs
|
|
500
|
+
drop_debugger: true
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
|
|
504
|
+
// Optimize chunk splitting
|
|
505
|
+
rollupOptions: {
|
|
506
|
+
output: {
|
|
507
|
+
manualChunks: {
|
|
508
|
+
// Separate vendor chunks
|
|
509
|
+
'vendor': ['igniteui-webcomponents'],
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
// Set chunk size warning limit
|
|
515
|
+
chunkSizeWarningLimit: 600,
|
|
516
|
+
},
|
|
517
|
+
|
|
518
|
+
// Optimize deps
|
|
519
|
+
optimizeDeps: {
|
|
520
|
+
include: ['igniteui-webcomponents']
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Webpack Configuration
|
|
526
|
+
|
|
527
|
+
```javascript
|
|
528
|
+
// webpack.config.js
|
|
529
|
+
module.exports = {
|
|
530
|
+
optimization: {
|
|
531
|
+
splitChunks: {
|
|
532
|
+
chunks: 'all',
|
|
533
|
+
cacheGroups: {
|
|
534
|
+
vendor: {
|
|
535
|
+
test: /[\\/]node_modules[\\/]/,
|
|
536
|
+
name: 'vendors',
|
|
537
|
+
priority: 10,
|
|
538
|
+
},
|
|
539
|
+
igniteui: {
|
|
540
|
+
test: /[\\/]node_modules[\\/]igniteui-webcomponents[\\/]/,
|
|
541
|
+
name: 'igniteui',
|
|
542
|
+
priority: 20,
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
minimize: true,
|
|
547
|
+
},
|
|
548
|
+
|
|
549
|
+
// Tree shaking
|
|
550
|
+
mode: 'production',
|
|
551
|
+
};
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## Size Comparison
|
|
555
|
+
|
|
556
|
+
Here's what you can expect in terms of bundle size:
|
|
557
|
+
|
|
558
|
+
| Import Strategy | Approximate Size (gzipped) | Components Included |
|
|
559
|
+
|----------------|---------------------------|---------------------|
|
|
560
|
+
| `defineAllComponents()` | ~500KB+ | All 60+ components |
|
|
561
|
+
| 10 components via `defineComponents()` | ~150-200KB | 10 components + deps |
|
|
562
|
+
| 5 components via `defineComponents()` | ~100-150KB | 5 components + deps |
|
|
563
|
+
| 3 components via `defineComponents()` | ~80-120KB | 3 components + deps |
|
|
564
|
+
| 1 component via `defineComponents()` | ~50-80KB | 1 component + deps |
|
|
565
|
+
|
|
566
|
+
**Note:** Sizes vary based on which components you import (some have more dependencies than others).
|
|
567
|
+
|
|
568
|
+
## Best Practices Checklist
|
|
569
|
+
|
|
570
|
+
- [ ] **Never use `defineAllComponents()`** unless you truly need every component
|
|
571
|
+
- [ ] **Use `defineComponents()` with specific components** you need
|
|
572
|
+
- [ ] **Audit your imports regularly** - remove unused components
|
|
573
|
+
- [ ] **Lazy load rarely-used components** (dialogs, modals, etc.)
|
|
574
|
+
- [ ] **Split by routes** - load components only for active routes
|
|
575
|
+
- [ ] **Analyze your bundle** - use bundle analyzer tools
|
|
576
|
+
- [ ] **Enable tree-shaking** - use named imports, not side-effect imports
|
|
577
|
+
- [ ] **Minify in production** - ensure build tool minification is enabled
|
|
578
|
+
- [ ] **Use compression** - enable gzip/brotli on your server
|
|
579
|
+
|
|
580
|
+
## Common Issues and Solutions
|
|
581
|
+
|
|
582
|
+
### Issue: Bundle still large after following best practices
|
|
583
|
+
|
|
584
|
+
**Investigate:**
|
|
585
|
+
|
|
586
|
+
1. Check if you're importing many components at once
|
|
587
|
+
2. Verify tree-shaking is working (check build output)
|
|
588
|
+
3. Look for duplicate dependencies
|
|
589
|
+
4. Check if source maps are included in production
|
|
590
|
+
5. For React, ensure you're using `igniteui-react` instead of `igniteui-webcomponents`
|
|
591
|
+
|
|
592
|
+
**Solutions:**
|
|
593
|
+
|
|
594
|
+
```typescript
|
|
595
|
+
// Review your imports - are you using all of these?
|
|
596
|
+
import {
|
|
597
|
+
defineComponents,
|
|
598
|
+
IgcButtonComponent,
|
|
599
|
+
IgcInputComponent,
|
|
600
|
+
IgcSelectComponent,
|
|
601
|
+
IgcComboComponent,
|
|
602
|
+
IgcDatePickerComponent
|
|
603
|
+
} from 'igniteui-webcomponents';
|
|
604
|
+
|
|
605
|
+
// Consider lazy loading components you don't need immediately
|
|
606
|
+
async function loadDialog() {
|
|
607
|
+
const { defineComponents, IgcDialogComponent } = await import('igniteui-webcomponents');
|
|
608
|
+
defineComponents(IgcDialogComponent);
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Issue: Components not working after optimizing imports
|
|
613
|
+
|
|
614
|
+
**Cause:** Forgot to import a component you're using
|
|
615
|
+
|
|
616
|
+
**Solution:**
|
|
617
|
+
|
|
618
|
+
```typescript
|
|
619
|
+
// Error: <igc-button> not working
|
|
620
|
+
// You're using igc-button but didn't import it
|
|
621
|
+
|
|
622
|
+
import { defineComponents, IgcButtonComponent } from 'igniteui-webcomponents';
|
|
623
|
+
defineComponents(IgcButtonComponent); // Add this
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Issue: TypeScript errors after changing imports
|
|
627
|
+
|
|
628
|
+
**Solution:** Update type imports:
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
// Import types separately if needed
|
|
632
|
+
import type { IgcButtonComponent } from 'igniteui-webcomponents';
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
## Monitoring Bundle Size
|
|
636
|
+
|
|
637
|
+
### Set up bundle size monitoring in CI/CD
|
|
638
|
+
|
|
639
|
+
**Using bundlesize (for any build tool):**
|
|
640
|
+
|
|
641
|
+
```bash
|
|
642
|
+
npm install --save-dev bundlesize
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
**Package.json:**
|
|
646
|
+
|
|
647
|
+
```json
|
|
648
|
+
{
|
|
649
|
+
"scripts": {
|
|
650
|
+
"test:size": "bundlesize"
|
|
651
|
+
},
|
|
652
|
+
"bundlesize": [
|
|
653
|
+
{
|
|
654
|
+
"path": "./dist/**/*.js",
|
|
655
|
+
"maxSize": "300 kB"
|
|
656
|
+
}
|
|
657
|
+
]
|
|
658
|
+
}
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**Run in CI:**
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
npm run build
|
|
665
|
+
npm run test:size
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### GitHub Actions Example
|
|
669
|
+
|
|
670
|
+
```yaml
|
|
671
|
+
name: Bundle Size Check
|
|
672
|
+
|
|
673
|
+
on: [pull_request]
|
|
674
|
+
|
|
675
|
+
jobs:
|
|
676
|
+
size:
|
|
677
|
+
runs-on: ubuntu-latest
|
|
678
|
+
steps:
|
|
679
|
+
- uses: actions/checkout@v3
|
|
680
|
+
- uses: actions/setup-node@v3
|
|
681
|
+
- run: npm ci
|
|
682
|
+
- run: npm run build
|
|
683
|
+
- run: npm run test:size
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
## Expected Results
|
|
687
|
+
|
|
688
|
+
After optimization, you should see:
|
|
689
|
+
|
|
690
|
+
- **Initial load time reduced** by 40-60%
|
|
691
|
+
- **Bundle size reduced** by 50-80%
|
|
692
|
+
- **Better Core Web Vitals** scores
|
|
693
|
+
- **Faster time to interactive**
|
|
694
|
+
- **Lower bandwidth usage** for users
|
|
695
|
+
|
|
696
|
+
## Next Steps
|
|
697
|
+
|
|
698
|
+
- Profile your application with Chrome DevTools Performance tab
|
|
699
|
+
- Implement lazy loading for heavy components
|
|
700
|
+
- Consider using CDN for static assets
|
|
701
|
+
- Enable HTTP/2 for better resource loading
|
|
702
|
+
- Check [igniteui-wc-integrate-with-framework](../igniteui-wc-integrate-with-framework/SKILL.md) for proper setup
|
|
703
|
+
|
|
704
|
+
## Additional Resources
|
|
705
|
+
|
|
706
|
+
- [Webpack Tree Shaking](https://webpack.js.org/guides/tree-shaking/)
|
|
707
|
+
- [Vite Build Optimizations](https://vitejs.dev/guide/build.html)
|
|
708
|
+
- [Web Performance Optimization](https://web.dev/fast/)
|
|
709
|
+
- [Bundle Size Analysis Tools](https://bundlephobia.com/)
|