claude-mpm 4.17.0__py3-none-any.whl → 4.18.0__py3-none-any.whl

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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (47) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +48 -17
  3. claude_mpm/agents/agent_loader.py +4 -4
  4. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  5. claude_mpm/config/agent_config.py +2 -2
  6. claude_mpm/core/factories.py +1 -1
  7. claude_mpm/core/optimized_agent_loader.py +3 -3
  8. claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
  9. claude_mpm/models/resume_log.py +340 -0
  10. claude_mpm/services/agents/auto_config_manager.py +1 -1
  11. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  12. claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
  13. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  14. claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
  15. claude_mpm/services/agents/local_template_manager.py +1 -1
  16. claude_mpm/services/core/path_resolver.py +1 -1
  17. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  18. claude_mpm/services/mcp_config_manager.py +2 -2
  19. claude_mpm/services/session_manager.py +205 -1
  20. claude_mpm/services/unified/deployment_strategies/local.py +1 -1
  21. claude_mpm/skills/bundled/api-documentation.md +393 -0
  22. claude_mpm/skills/bundled/async-testing.md +571 -0
  23. claude_mpm/skills/bundled/code-review.md +143 -0
  24. claude_mpm/skills/bundled/database-migration.md +199 -0
  25. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  26. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  27. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  28. claude_mpm/skills/bundled/git-workflow.md +414 -0
  29. claude_mpm/skills/bundled/imagemagick.md +204 -0
  30. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  31. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  32. claude_mpm/skills/bundled/pdf.md +141 -0
  33. claude_mpm/skills/bundled/performance-profiling.md +567 -0
  34. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  35. claude_mpm/skills/bundled/security-scanning.md +327 -0
  36. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  37. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  38. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  39. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  40. claude_mpm/skills/bundled/xlsx.md +157 -0
  41. claude_mpm/utils/agent_dependency_loader.py +2 -2
  42. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/METADATA +68 -1
  43. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/RECORD +47 -24
  44. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/WHEEL +0 -0
  45. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/entry_points.txt +0 -0
  46. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/licenses/LICENSE +0 -0
  47. {claude_mpm-4.17.0.dist-info → claude_mpm-4.18.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,2305 @@
1
+ ---
2
+ skill_id: web-performance-optimization
3
+ skill_version: 0.1.0
4
+ description: Comprehensive guide to optimizing web performance using Lighthouse metrics and Core Web Vitals, covering modern optimization techniques and measurement strategies.
5
+ updated_at: 2025-10-30T17:00:00Z
6
+ tags: [performance, optimization, lighthouse, core-web-vitals, frontend]
7
+ ---
8
+
9
+ # Web Performance Optimization
10
+
11
+ ## Overview
12
+
13
+ Comprehensive guide to optimizing web performance using Lighthouse metrics and Core Web Vitals (updated for 2024-2025). This skill covers modern performance optimization techniques, measurement strategies, and framework-specific optimizations to deliver fast, responsive user experiences.
14
+
15
+ Web performance directly impacts user experience, conversions, and SEO rankings. Studies show that a 1-second delay can result in 7% conversion loss, while 0.1s improvements can increase conversions by 8%. This guide provides actionable strategies to optimize every aspect of web performance.
16
+
17
+ ## When to Use This Skill
18
+
19
+ - Auditing website performance metrics
20
+ - Improving Lighthouse scores and Core Web Vitals
21
+ - Optimizing page load times and interactivity
22
+ - Reducing resource sizes and improving caching
23
+ - Enhancing SEO rankings through performance signals
24
+ - Improving user experience and conversion rates
25
+ - Debugging performance bottlenecks
26
+ - Setting up performance monitoring and budgets
27
+ - Implementing modern performance patterns (streaming SSR, islands architecture)
28
+
29
+ ## Core Web Vitals (2024-2025)
30
+
31
+ Core Web Vitals are Google's essential metrics for measuring user experience. These metrics are ranking factors for SEO and directly correlate with user satisfaction and conversions.
32
+
33
+ ### LCP (Largest Contentful Paint)
34
+
35
+ **Target:** ≤2.5 seconds (Good), 2.5-4.0s (Needs Improvement), >4.0s (Poor)
36
+
37
+ **What it Measures:** Time until the largest content element (image, video, or text block) becomes visible in the viewport. For 73% of sites, LCP is caused by images.
38
+
39
+ **Optimization Strategies:**
40
+
41
+ #### 1. Image Optimization
42
+ ```html
43
+ <!-- Use modern formats with fallbacks -->
44
+ <picture>
45
+ <source srcset="hero.avif" type="image/avif">
46
+ <source srcset="hero.webp" type="image/webp">
47
+ <img src="hero.jpg" alt="Hero image" fetchpriority="high">
48
+ </picture>
49
+
50
+ <!-- Responsive images with srcset -->
51
+ <img
52
+ srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
53
+ sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
54
+ src="hero-800.webp"
55
+ alt="Hero image"
56
+ fetchpriority="high"
57
+ >
58
+ ```
59
+
60
+ #### 2. Preload Critical Resources
61
+ ```html
62
+ <!-- Preload LCP image -->
63
+ <link rel="preload" as="image" href="hero.webp" fetchpriority="high">
64
+
65
+ <!-- Preload critical fonts -->
66
+ <link rel="preload" as="font" type="font/woff2" href="/fonts/main.woff2" crossorigin>
67
+ ```
68
+
69
+ #### 3. Server-Side Optimizations
70
+ ```nginx
71
+ # Enable 103 Early Hints (25-37% improvement)
72
+ # Nginx configuration
73
+ add_header Link "</css/critical.css>; rel=preload; as=style" always;
74
+ add_header Link "</fonts/main.woff2>; rel=preload; as=font; crossorigin" always;
75
+ ```
76
+
77
+ #### 4. CDN and Image Services
78
+ ```javascript
79
+ // Cloudinary automatic optimization
80
+ const imageUrl = cloudinary.url('sample.jpg', {
81
+ fetch_format: 'auto', // Automatically choose WebP/AVIF
82
+ quality: 'auto', // Optimize quality
83
+ width: 800,
84
+ crop: 'scale'
85
+ });
86
+ ```
87
+
88
+ #### 5. Lazy Loading (Non-LCP Images Only)
89
+ ```html
90
+ <!-- DO NOT lazy load LCP images -->
91
+ <img src="hero.webp" alt="Hero" fetchpriority="high">
92
+
93
+ <!-- DO lazy load below-the-fold images -->
94
+ <img src="content.webp" alt="Content" loading="lazy">
95
+ ```
96
+
97
+ ### INP (Interaction to Next Paint) - NEW March 2024
98
+
99
+ **Target:** ≤200ms (Good), 200-500ms (Needs Improvement), >500ms (Poor)
100
+
101
+ **What it Measures:** Responsiveness to user interactions (clicks, taps, keyboard input). INP replaced FID (First Input Delay) as a Core Web Vital in March 2024, providing a more comprehensive measure of interaction responsiveness throughout the page lifecycle.
102
+
103
+ **Optimization Strategies:**
104
+
105
+ #### 1. Reduce Long Tasks
106
+ ```javascript
107
+ // BAD: Long blocking task
108
+ function processLargeDataset(data) {
109
+ data.forEach(item => heavyComputation(item));
110
+ }
111
+
112
+ // GOOD: Break into smaller tasks with yielding
113
+ async function processLargeDataset(data) {
114
+ for (let i = 0; i < data.length; i++) {
115
+ heavyComputation(data[i]);
116
+
117
+ // Yield to main thread every 50ms
118
+ if (i % 100 === 0) {
119
+ await new Promise(resolve => setTimeout(resolve, 0));
120
+ }
121
+ }
122
+ }
123
+
124
+ // BETTER: Use scheduler.yield() (when available)
125
+ async function processLargeDataset(data) {
126
+ for (let i = 0; i < data.length; i++) {
127
+ heavyComputation(data[i]);
128
+
129
+ if (i % 100 === 0 && 'scheduler' in window) {
130
+ await scheduler.yield();
131
+ }
132
+ }
133
+ }
134
+ ```
135
+
136
+ #### 2. Debounce Input Handlers
137
+ ```javascript
138
+ // Debounce expensive operations
139
+ function debounce(func, wait) {
140
+ let timeout;
141
+ return function executedFunction(...args) {
142
+ clearTimeout(timeout);
143
+ timeout = setTimeout(() => func(...args), wait);
144
+ };
145
+ }
146
+
147
+ // Usage
148
+ const handleSearch = debounce((query) => {
149
+ fetchSearchResults(query);
150
+ }, 300);
151
+
152
+ input.addEventListener('input', (e) => handleSearch(e.target.value));
153
+ ```
154
+
155
+ #### 3. Use Web Workers for Heavy Computations
156
+ ```javascript
157
+ // main.js
158
+ const worker = new Worker('worker.js');
159
+
160
+ button.addEventListener('click', () => {
161
+ worker.postMessage({ data: largeDataset });
162
+ });
163
+
164
+ worker.onmessage = (e) => {
165
+ updateUI(e.data.result);
166
+ };
167
+
168
+ // worker.js
169
+ self.onmessage = (e) => {
170
+ const result = heavyComputation(e.data);
171
+ self.postMessage({ result });
172
+ };
173
+ ```
174
+
175
+ #### 4. Optimize React Event Handlers
176
+ ```javascript
177
+ // BAD: Creating new function on every render
178
+ function SearchComponent() {
179
+ return <input onChange={(e) => handleChange(e.target.value)} />;
180
+ }
181
+
182
+ // GOOD: Memoized callback
183
+ function SearchComponent() {
184
+ const handleChange = useCallback((e) => {
185
+ // Handle change
186
+ }, []);
187
+
188
+ return <input onChange={handleChange} />;
189
+ }
190
+ ```
191
+
192
+ #### 5. CSS Containment for Faster Rendering
193
+ ```css
194
+ /* Isolate rendering work to specific containers */
195
+ .card {
196
+ contain: layout style paint;
197
+ }
198
+
199
+ .list-item {
200
+ content-visibility: auto;
201
+ contain-intrinsic-size: 0 200px;
202
+ }
203
+ ```
204
+
205
+ ### CLS (Cumulative Layout Shift)
206
+
207
+ **Target:** ≤0.1 (Good), 0.1-0.25 (Needs Improvement), >0.25 (Poor)
208
+
209
+ **What it Measures:** Visual stability - unexpected layout shifts during page load and user interaction.
210
+
211
+ **Optimization Strategies:**
212
+
213
+ #### 1. Reserve Space for Images and Embeds
214
+ ```html
215
+ <!-- Always include width and height attributes -->
216
+ <img src="photo.jpg" alt="Photo" width="800" height="600">
217
+
218
+ <!-- CSS aspect ratio (modern) -->
219
+ <style>
220
+ .image-container {
221
+ aspect-ratio: 16 / 9;
222
+ width: 100%;
223
+ }
224
+
225
+ .image-container img {
226
+ width: 100%;
227
+ height: 100%;
228
+ object-fit: cover;
229
+ }
230
+ </style>
231
+ ```
232
+
233
+ #### 2. Reserve Space for Dynamic Content
234
+ ```css
235
+ /* Reserve minimum height for dynamic content */
236
+ .dynamic-content {
237
+ min-height: 400px;
238
+ }
239
+
240
+ /* Skeleton screens */
241
+ .skeleton {
242
+ background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
243
+ background-size: 200% 100%;
244
+ animation: loading 1.5s infinite;
245
+ }
246
+
247
+ @keyframes loading {
248
+ 0% { background-position: 200% 0; }
249
+ 100% { background-position: -200% 0; }
250
+ }
251
+ ```
252
+
253
+ #### 3. Avoid Inserting Content Above Existing Content
254
+ ```javascript
255
+ // BAD: Prepending content causes shift
256
+ container.innerHTML = newContent + container.innerHTML;
257
+
258
+ // GOOD: Append or use proper animations
259
+ container.insertAdjacentHTML('beforeend', newContent);
260
+
261
+ // BETTER: Animate new content in
262
+ container.style.transform = 'translateY(100px)';
263
+ container.innerHTML = newContent;
264
+ requestAnimationFrame(() => {
265
+ container.style.transform = 'translateY(0)';
266
+ container.style.transition = 'transform 0.3s';
267
+ });
268
+ ```
269
+
270
+ #### 4. Font Loading Optimization
271
+ ```html
272
+ <!-- Preload critical fonts -->
273
+ <link rel="preload" as="font" type="font/woff2" href="/fonts/main.woff2" crossorigin>
274
+
275
+ <style>
276
+ /* font-display: swap prevents invisible text but may cause shift */
277
+ /* font-display: optional is better for CLS */
278
+ @font-face {
279
+ font-family: 'Main Font';
280
+ src: url('/fonts/main.woff2') format('woff2');
281
+ font-display: optional;
282
+ }
283
+
284
+ /* Fallback font metrics matching */
285
+ body {
286
+ font-family: 'Main Font', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
287
+ }
288
+ </style>
289
+ ```
290
+
291
+ #### 5. Ad and Embed Containers
292
+ ```html
293
+ <!-- Reserve space for ads -->
294
+ <div class="ad-container" style="min-height: 250px;">
295
+ <!-- Ad loads here -->
296
+ </div>
297
+
298
+ <!-- YouTube embed with aspect ratio -->
299
+ <div style="aspect-ratio: 16/9; width: 100%;">
300
+ <iframe
301
+ src="https://www.youtube.com/embed/VIDEO_ID"
302
+ style="width: 100%; height: 100%;"
303
+ loading="lazy"
304
+ ></iframe>
305
+ </div>
306
+ ```
307
+
308
+ ### Supporting Metrics
309
+
310
+ #### FCP (First Contentful Paint)
311
+
312
+ **Target:** <1.8 seconds (Good), 1.8-3.0s (Needs Improvement), >3.0s (Poor)
313
+
314
+ **What it Measures:** Time until the first text or image is painted.
315
+
316
+ **Optimization:**
317
+ - Minimize render-blocking resources (CSS, JS)
318
+ - Use critical CSS inline in `<head>`
319
+ - Defer non-critical JavaScript
320
+ - Optimize server response times (TTFB)
321
+
322
+ ```html
323
+ <!-- Inline critical CSS -->
324
+ <style>
325
+ /* Above-the-fold styles */
326
+ body { margin: 0; font-family: system-ui; }
327
+ .hero { height: 100vh; }
328
+ </style>
329
+
330
+ <!-- Defer non-critical CSS -->
331
+ <link rel="preload" as="style" href="main.css" onload="this.onload=null;this.rel='stylesheet'">
332
+ <noscript><link rel="stylesheet" href="main.css"></noscript>
333
+ ```
334
+
335
+ #### TTFB (Time to First Byte)
336
+
337
+ **Target:** <800ms (Good), 800-1800ms (Needs Improvement), >1800ms (Poor)
338
+
339
+ **What it Measures:** Server response time.
340
+
341
+ **Optimization:**
342
+ - Use CDN edge caching
343
+ - Enable server-side caching (Redis, Memcached)
344
+ - Optimize database queries
345
+ - Enable HTTP/2 or HTTP/3
346
+ - Use 103 Early Hints
347
+
348
+ #### TBT (Total Blocking Time)
349
+
350
+ **Weight:** 30% (highest in Lighthouse v12)
351
+
352
+ **Target:** <200ms (Good), 200-600ms (Needs Improvement), >600ms (Poor)
353
+
354
+ **What it Measures:** Total time the main thread was blocked by long tasks (>50ms).
355
+
356
+ **Optimization:**
357
+ - Code splitting to reduce JavaScript execution time
358
+ - Defer non-critical JavaScript
359
+ - Break up long tasks
360
+ - Remove unused code
361
+ - Optimize third-party scripts
362
+
363
+ ## Lighthouse Scoring (v12 - August 2024)
364
+
365
+ ### Performance Score Weights
366
+
367
+ Lighthouse v12 (released August 2024) updated performance scoring weights:
368
+
369
+ - **Total Blocking Time (TBT):** 30% - HIGHEST WEIGHT
370
+ - **Largest Contentful Paint (LCP):** 25%
371
+ - **Cumulative Layout Shift (CLS):** 25%
372
+ - **First Contentful Paint (FCP):** 10%
373
+ - **Speed Index:** 10%
374
+
375
+ ### Scoring Calculation
376
+
377
+ Each metric has a curve that maps raw values to scores (0-100):
378
+
379
+ ```javascript
380
+ // Example scoring curve (simplified)
381
+ function calculateScore(metrics) {
382
+ const weights = {
383
+ TBT: 0.30,
384
+ LCP: 0.25,
385
+ CLS: 0.25,
386
+ FCP: 0.10,
387
+ SI: 0.10
388
+ };
389
+
390
+ // Each metric is scored on a curve
391
+ const scores = {
392
+ TBT: scoreFromValue(metrics.TBT, TBT_CURVE),
393
+ LCP: scoreFromValue(metrics.LCP, LCP_CURVE),
394
+ CLS: scoreFromValue(metrics.CLS, CLS_CURVE),
395
+ FCP: scoreFromValue(metrics.FCP, FCP_CURVE),
396
+ SI: scoreFromValue(metrics.SI, SI_CURVE)
397
+ };
398
+
399
+ // Weighted average
400
+ return Object.keys(weights).reduce((total, metric) => {
401
+ return total + (scores[metric] * weights[metric]);
402
+ }, 0);
403
+ }
404
+ ```
405
+
406
+ ### Running Lighthouse
407
+
408
+ ```bash
409
+ # CLI audit
410
+ lighthouse https://example.com --view --output html --output-path ./report.html
411
+
412
+ # With specific categories
413
+ lighthouse https://example.com --only-categories=performance
414
+
415
+ # Mobile simulation (default)
416
+ lighthouse https://example.com --preset=mobile
417
+
418
+ # Desktop audit
419
+ lighthouse https://example.com --preset=desktop
420
+
421
+ # CI/CD integration
422
+ lighthouse https://example.com --output=json --output-path=./lighthouse.json
423
+ ```
424
+
425
+ ## Image Optimization
426
+
427
+ Images account for 73% of LCP elements and are the largest contributor to page weight. Modern image optimization is essential for performance.
428
+
429
+ ### Modern Formats
430
+
431
+ **WebP/AVIF:** 96% browser support (2024)
432
+
433
+ ```html
434
+ <!-- Progressive enhancement with multiple formats -->
435
+ <picture>
436
+ <source srcset="image.avif" type="image/avif">
437
+ <source srcset="image.webp" type="image/webp">
438
+ <img src="image.jpg" alt="Description" width="800" height="600">
439
+ </picture>
440
+ ```
441
+
442
+ **Format Comparison:**
443
+ - AVIF: 50% smaller than JPEG, excellent quality
444
+ - WebP: 30% smaller than JPEG, great browser support
445
+ - JPEG: Universal support, baseline format
446
+
447
+ ### Responsive Images
448
+
449
+ ```html
450
+ <!-- Density descriptors for different screen densities -->
451
+ <img
452
+ srcset="image-1x.jpg 1x, image-2x.jpg 2x, image-3x.jpg 3x"
453
+ src="image-1x.jpg"
454
+ alt="Description"
455
+ >
456
+
457
+ <!-- Width descriptors with sizes attribute -->
458
+ <img
459
+ srcset="
460
+ image-400.jpg 400w,
461
+ image-800.jpg 800w,
462
+ image-1200.jpg 1200w,
463
+ image-1600.jpg 1600w
464
+ "
465
+ sizes="
466
+ (max-width: 600px) 100vw,
467
+ (max-width: 1200px) 50vw,
468
+ 800px
469
+ "
470
+ src="image-800.jpg"
471
+ alt="Description"
472
+ >
473
+
474
+ <!-- Art direction with picture element -->
475
+ <picture>
476
+ <source media="(min-width: 1200px)" srcset="hero-wide.jpg">
477
+ <source media="(min-width: 600px)" srcset="hero-medium.jpg">
478
+ <img src="hero-small.jpg" alt="Hero image">
479
+ </picture>
480
+ ```
481
+
482
+ ### Lazy Loading
483
+
484
+ ```html
485
+ <!-- Native lazy loading (DO NOT use on LCP images) -->
486
+ <img src="image.jpg" loading="lazy" alt="Below fold image">
487
+
488
+ <!-- Eager loading for above-fold images -->
489
+ <img src="hero.jpg" loading="eager" fetchpriority="high" alt="Hero">
490
+ ```
491
+
492
+ **JavaScript lazy loading with Intersection Observer:**
493
+
494
+ ```javascript
495
+ const imageObserver = new IntersectionObserver((entries, observer) => {
496
+ entries.forEach(entry => {
497
+ if (entry.isIntersecting) {
498
+ const img = entry.target;
499
+ img.src = img.dataset.src;
500
+ img.classList.remove('lazy');
501
+ observer.unobserve(img);
502
+ }
503
+ });
504
+ });
505
+
506
+ document.querySelectorAll('img.lazy').forEach(img => {
507
+ imageObserver.observe(img);
508
+ });
509
+ ```
510
+
511
+ ### Image CDN Strategies
512
+
513
+ **Cloudinary:**
514
+ ```javascript
515
+ // Automatic format and quality optimization
516
+ const url = cloudinary.url('sample.jpg', {
517
+ fetch_format: 'auto',
518
+ quality: 'auto',
519
+ width: 800,
520
+ crop: 'scale',
521
+ dpr: 'auto' // Automatically handle device pixel ratio
522
+ });
523
+ ```
524
+
525
+ **Imgix:**
526
+ ```javascript
527
+ // Dynamic image transformation
528
+ const imgixUrl = `https://domain.imgix.net/image.jpg?w=800&auto=format,compress&fit=crop`;
529
+ ```
530
+
531
+ **Next.js Image Component:**
532
+ ```jsx
533
+ import Image from 'next/image';
534
+
535
+ // Automatic optimization, lazy loading, and responsive images
536
+ <Image
537
+ src="/hero.jpg"
538
+ alt="Hero image"
539
+ width={1200}
540
+ height={600}
541
+ priority // Disable lazy loading for LCP image
542
+ quality={85}
543
+ />
544
+ ```
545
+
546
+ ## JavaScript Optimization
547
+
548
+ JavaScript is often the primary bottleneck for TBT and INP. Optimizing JavaScript delivery and execution is critical.
549
+
550
+ ### Code Splitting
551
+
552
+ **Impact:** 40-60% bundle size reduction
553
+
554
+ ```javascript
555
+ // React lazy loading
556
+ import React, { lazy, Suspense } from 'react';
557
+
558
+ const HeavyComponent = lazy(() => import('./HeavyComponent'));
559
+
560
+ function App() {
561
+ return (
562
+ <Suspense fallback={<div>Loading...</div>}>
563
+ <HeavyComponent />
564
+ </Suspense>
565
+ );
566
+ }
567
+
568
+ // Route-based code splitting
569
+ import { lazy } from 'react';
570
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
571
+
572
+ const Home = lazy(() => import('./pages/Home'));
573
+ const Dashboard = lazy(() => import('./pages/Dashboard'));
574
+ const Settings = lazy(() => import('./pages/Settings'));
575
+
576
+ function App() {
577
+ return (
578
+ <BrowserRouter>
579
+ <Suspense fallback={<LoadingSpinner />}>
580
+ <Routes>
581
+ <Route path="/" element={<Home />} />
582
+ <Route path="/dashboard" element={<Dashboard />} />
583
+ <Route path="/settings" element={<Settings />} />
584
+ </Routes>
585
+ </Suspense>
586
+ </BrowserRouter>
587
+ );
588
+ }
589
+ ```
590
+
591
+ **Webpack configuration:**
592
+ ```javascript
593
+ // webpack.config.js
594
+ module.exports = {
595
+ optimization: {
596
+ splitChunks: {
597
+ chunks: 'all',
598
+ cacheGroups: {
599
+ vendor: {
600
+ test: /[\\/]node_modules[\\/]/,
601
+ name: 'vendors',
602
+ priority: 10
603
+ },
604
+ common: {
605
+ minChunks: 2,
606
+ name: 'common',
607
+ priority: 5
608
+ }
609
+ }
610
+ }
611
+ }
612
+ };
613
+ ```
614
+
615
+ ### Tree Shaking
616
+
617
+ Remove unused code from bundles:
618
+
619
+ ```javascript
620
+ // package.json
621
+ {
622
+ "sideEffects": false // Enable tree shaking
623
+ }
624
+
625
+ // Or specify files with side effects
626
+ {
627
+ "sideEffects": ["*.css", "*.scss"]
628
+ }
629
+
630
+ // Import only what you need
631
+ import { debounce } from 'lodash-es'; // Good: ES modules
632
+ import debounce from 'lodash/debounce'; // Good: Individual module
633
+
634
+ import _ from 'lodash'; // Bad: Imports entire library
635
+ ```
636
+
637
+ **Vite tree shaking (automatic):**
638
+ ```javascript
639
+ // vite.config.js
640
+ export default {
641
+ build: {
642
+ minify: 'terser',
643
+ terserOptions: {
644
+ compress: {
645
+ drop_console: true,
646
+ drop_debugger: true,
647
+ pure_funcs: ['console.log']
648
+ }
649
+ }
650
+ }
651
+ };
652
+ ```
653
+
654
+ ### Lazy Loading Modules
655
+
656
+ ```javascript
657
+ // Dynamic imports
658
+ button.addEventListener('click', async () => {
659
+ const { default: Chart } = await import('chart.js');
660
+ const chart = new Chart(ctx, config);
661
+ });
662
+
663
+ // Preload for faster loading
664
+ const ChartPromise = import(/* webpackPrefetch: true */ 'chart.js');
665
+
666
+ button.addEventListener('click', async () => {
667
+ const { default: Chart } = await ChartPromise;
668
+ const chart = new Chart(ctx, config);
669
+ });
670
+ ```
671
+
672
+ ### Bundle Analysis
673
+
674
+ ```bash
675
+ # webpack-bundle-analyzer
676
+ npm install --save-dev webpack-bundle-analyzer
677
+
678
+ # Add to webpack config
679
+ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
680
+
681
+ module.exports = {
682
+ plugins: [
683
+ new BundleAnalyzerPlugin()
684
+ ]
685
+ };
686
+
687
+ # Run build
688
+ npm run build
689
+ ```
690
+
691
+ **Vite bundle analysis:**
692
+ ```bash
693
+ # Install rollup-plugin-visualizer
694
+ npm install --save-dev rollup-plugin-visualizer
695
+
696
+ # vite.config.js
697
+ import { visualizer } from 'rollup-plugin-visualizer';
698
+
699
+ export default {
700
+ plugins: [
701
+ visualizer({
702
+ open: true,
703
+ gzipSize: true,
704
+ brotliSize: true
705
+ })
706
+ ]
707
+ };
708
+ ```
709
+
710
+ ### Third-Party Scripts
711
+
712
+ **Problem:** 90%+ sites affected by third-party bloat
713
+
714
+ **Strategies:**
715
+
716
+ ```html
717
+ <!-- 1. Defer non-critical scripts -->
718
+ <script src="analytics.js" defer></script>
719
+
720
+ <!-- 2. Use async for independent scripts -->
721
+ <script src="tracking.js" async></script>
722
+
723
+ <!-- 3. Lazy load based on user interaction -->
724
+ <script>
725
+ let analyticsLoaded = false;
726
+
727
+ function loadAnalytics() {
728
+ if (analyticsLoaded) return;
729
+ analyticsLoaded = true;
730
+
731
+ const script = document.createElement('script');
732
+ script.src = 'https://analytics.example.com/script.js';
733
+ document.head.appendChild(script);
734
+ }
735
+
736
+ // Load on first interaction
737
+ ['click', 'scroll', 'keydown'].forEach(event => {
738
+ window.addEventListener(event, loadAnalytics, { once: true });
739
+ });
740
+
741
+ // Fallback: load after 5 seconds
742
+ setTimeout(loadAnalytics, 5000);
743
+ </script>
744
+
745
+ <!-- 4. Use facade pattern for heavy embeds -->
746
+ <div class="youtube-facade" data-video-id="VIDEO_ID">
747
+ <button class="play-button">Play Video</button>
748
+ </div>
749
+
750
+ <script>
751
+ document.querySelectorAll('.youtube-facade').forEach(facade => {
752
+ facade.addEventListener('click', function() {
753
+ const iframe = document.createElement('iframe');
754
+ iframe.src = `https://www.youtube.com/embed/${this.dataset.videoId}?autoplay=1`;
755
+ iframe.allow = 'autoplay';
756
+ this.replaceWith(iframe);
757
+ });
758
+ });
759
+ </script>
760
+ ```
761
+
762
+ **Partytown for web workers:**
763
+ ```html
764
+ <!-- Move third-party scripts to web worker -->
765
+ <script type="text/partytown" src="analytics.js"></script>
766
+ <script type="text/partytown">
767
+ // This runs in a web worker
768
+ gtag('config', 'GA_MEASUREMENT_ID');
769
+ </script>
770
+ ```
771
+
772
+ ## CSS Optimization
773
+
774
+ ### Critical CSS Extraction
775
+
776
+ Extract and inline above-the-fold CSS:
777
+
778
+ ```bash
779
+ # Using Critical package
780
+ npm install --save-dev critical
781
+
782
+ # Generate critical CSS
783
+ npx critical https://example.com --inline --minify
784
+ ```
785
+
786
+ ```javascript
787
+ // Build script with critical CSS
788
+ const critical = require('critical');
789
+
790
+ critical.generate({
791
+ inline: true,
792
+ base: 'dist/',
793
+ src: 'index.html',
794
+ target: {
795
+ html: 'index-critical.html',
796
+ css: 'critical.css'
797
+ },
798
+ dimensions: [
799
+ { width: 375, height: 667 }, // Mobile
800
+ { width: 1920, height: 1080 } // Desktop
801
+ ]
802
+ });
803
+ ```
804
+
805
+ ### Unused CSS Removal
806
+
807
+ **Impact:** 80-90% reduction with PurgeCSS
808
+
809
+ ```javascript
810
+ // PostCSS with PurgeCSS
811
+ // postcss.config.js
812
+ module.exports = {
813
+ plugins: [
814
+ require('@fullhuman/postcss-purgecss')({
815
+ content: ['./src/**/*.html', './src/**/*.js', './src/**/*.jsx'],
816
+ defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
817
+ safelist: ['active', 'disabled', /^data-/] // Preserve dynamic classes
818
+ })
819
+ ]
820
+ };
821
+ ```
822
+
823
+ **Tailwind CSS automatic purging:**
824
+ ```javascript
825
+ // tailwind.config.js
826
+ module.exports = {
827
+ content: [
828
+ './src/**/*.{js,jsx,ts,tsx,html}',
829
+ './public/index.html'
830
+ ],
831
+ theme: {
832
+ extend: {}
833
+ }
834
+ };
835
+ ```
836
+
837
+ ### Modern CSS Features
838
+
839
+ ```css
840
+ /* Container queries for responsive components */
841
+ .card-container {
842
+ container-type: inline-size;
843
+ }
844
+
845
+ @container (min-width: 400px) {
846
+ .card {
847
+ display: grid;
848
+ grid-template-columns: 1fr 2fr;
849
+ }
850
+ }
851
+
852
+ /* :has() for parent selection */
853
+ .article:has(img) {
854
+ display: grid;
855
+ grid-template-columns: 1fr 1fr;
856
+ }
857
+
858
+ /* CSS containment for performance */
859
+ .card {
860
+ contain: layout style paint;
861
+ }
862
+
863
+ .list-item {
864
+ content-visibility: auto;
865
+ contain-intrinsic-size: 0 200px;
866
+ }
867
+
868
+ /* Native CSS nesting */
869
+ .component {
870
+ padding: 1rem;
871
+
872
+ & .title {
873
+ font-size: 1.5rem;
874
+ }
875
+
876
+ &:hover {
877
+ background: #f0f0f0;
878
+ }
879
+ }
880
+ ```
881
+
882
+ ## Resource Loading Optimization
883
+
884
+ ### Resource Hints
885
+
886
+ ```html
887
+ <!-- Preconnect: Establish early connections to critical third-party origins -->
888
+ <link rel="preconnect" href="https://fonts.googleapis.com">
889
+ <link rel="preconnect" href="https://cdn.example.com">
890
+
891
+ <!-- DNS-prefetch: Resolve DNS only (lighter than preconnect) -->
892
+ <link rel="dns-prefetch" href="https://analytics.example.com">
893
+
894
+ <!-- Preload: Fetch critical resources early -->
895
+ <link rel="preload" as="image" href="hero.webp" fetchpriority="high">
896
+ <link rel="preload" as="font" type="font/woff2" href="main.woff2" crossorigin>
897
+ <link rel="preload" as="script" href="critical.js">
898
+ <link rel="preload" as="style" href="critical.css">
899
+
900
+ <!-- Prefetch: Fetch resources for next navigation (low priority) -->
901
+ <link rel="prefetch" as="document" href="/next-page.html">
902
+ <link rel="prefetch" as="script" href="next-page.js">
903
+
904
+ <!-- Modulepreload: Preload ES modules -->
905
+ <link rel="modulepreload" href="app.js">
906
+ ```
907
+
908
+ ### Priority Hints API
909
+
910
+ ```html
911
+ <!-- High priority for critical images -->
912
+ <img src="hero.jpg" fetchpriority="high" alt="Hero">
913
+
914
+ <!-- Low priority for below-fold images -->
915
+ <img src="footer-logo.jpg" fetchpriority="low" alt="Logo">
916
+
917
+ <!-- Script prioritization -->
918
+ <script src="critical.js" fetchpriority="high"></script>
919
+ <script src="analytics.js" fetchpriority="low" async></script>
920
+ ```
921
+
922
+ ### 103 Early Hints
923
+
924
+ **Impact:** 25-37% improvement in page load times
925
+
926
+ **Server configuration (Nginx):**
927
+ ```nginx
928
+ location / {
929
+ add_header Link "</css/critical.css>; rel=preload; as=style" always;
930
+ add_header Link "</js/main.js>; rel=preload; as=script" always;
931
+ add_header Link "</fonts/main.woff2>; rel=preload; as=font; crossorigin" always;
932
+
933
+ # Return 103 Early Hints
934
+ return 103;
935
+ }
936
+ ```
937
+
938
+ **Node.js/Express:**
939
+ ```javascript
940
+ app.use((req, res, next) => {
941
+ res.writeProcessing(); // 103 Early Hints
942
+ res.setHeader('Link', [
943
+ '</css/critical.css>; rel=preload; as=style',
944
+ '</js/main.js>; rel=preload; as=script',
945
+ '</fonts/main.woff2>; rel=preload; as=font; crossorigin'
946
+ ].join(', '));
947
+ next();
948
+ });
949
+ ```
950
+
951
+ ### HTTP/2 and HTTP/3
952
+
953
+ **Benefits:**
954
+ - Multiplexing: Multiple requests over single connection
955
+ - Header compression (HPACK)
956
+ - Server push (HTTP/2)
957
+ - Improved reliability over UDP (HTTP/3 with QUIC)
958
+
959
+ **Enable in Nginx:**
960
+ ```nginx
961
+ server {
962
+ listen 443 ssl http2;
963
+ listen 443 http3 reuseport; # HTTP/3
964
+
965
+ add_header Alt-Svc 'h3=":443"; ma=86400'; # Advertise HTTP/3
966
+
967
+ ssl_certificate /path/to/cert.pem;
968
+ ssl_certificate_key /path/to/key.pem;
969
+ ssl_protocols TLSv1.2 TLSv1.3;
970
+ }
971
+ ```
972
+
973
+ ## Caching Strategies
974
+
975
+ ### Cache-Control Headers
976
+
977
+ ```nginx
978
+ # Nginx configuration
979
+ location ~* \.(jpg|jpeg|png|gif|webp|avif)$ {
980
+ expires 1y;
981
+ add_header Cache-Control "public, immutable";
982
+ }
983
+
984
+ location ~* \.(css|js)$ {
985
+ expires 1y;
986
+ add_header Cache-Control "public, immutable";
987
+ }
988
+
989
+ location ~* \.(html)$ {
990
+ expires -1;
991
+ add_header Cache-Control "no-cache, must-revalidate";
992
+ }
993
+
994
+ # Stale-while-revalidate for API responses
995
+ location /api/ {
996
+ add_header Cache-Control "max-age=60, stale-while-revalidate=600";
997
+ }
998
+ ```
999
+
1000
+ **Express.js:**
1001
+ ```javascript
1002
+ // Static assets with long cache
1003
+ app.use('/static', express.static('public', {
1004
+ maxAge: '1y',
1005
+ immutable: true
1006
+ }));
1007
+
1008
+ // API with stale-while-revalidate
1009
+ app.get('/api/data', (req, res) => {
1010
+ res.set('Cache-Control', 'max-age=60, stale-while-revalidate=600');
1011
+ res.json(data);
1012
+ });
1013
+ ```
1014
+
1015
+ ### Service Workers
1016
+
1017
+ ```javascript
1018
+ // sw.js - Service worker with Workbox
1019
+ import { precacheAndRoute } from 'workbox-precaching';
1020
+ import { registerRoute } from 'workbox-routing';
1021
+ import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
1022
+ import { ExpirationPlugin } from 'workbox-expiration';
1023
+
1024
+ // Precache static assets
1025
+ precacheAndRoute(self.__WB_MANIFEST);
1026
+
1027
+ // Cache images with CacheFirst strategy
1028
+ registerRoute(
1029
+ ({ request }) => request.destination === 'image',
1030
+ new CacheFirst({
1031
+ cacheName: 'images',
1032
+ plugins: [
1033
+ new ExpirationPlugin({
1034
+ maxEntries: 60,
1035
+ maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
1036
+ }),
1037
+ ],
1038
+ })
1039
+ );
1040
+
1041
+ // Cache API requests with NetworkFirst
1042
+ registerRoute(
1043
+ ({ url }) => url.pathname.startsWith('/api/'),
1044
+ new NetworkFirst({
1045
+ cacheName: 'api-cache',
1046
+ plugins: [
1047
+ new ExpirationPlugin({
1048
+ maxEntries: 50,
1049
+ maxAgeSeconds: 5 * 60, // 5 minutes
1050
+ }),
1051
+ ],
1052
+ })
1053
+ );
1054
+
1055
+ // Cache CSS/JS with StaleWhileRevalidate
1056
+ registerRoute(
1057
+ ({ request }) => request.destination === 'script' || request.destination === 'style',
1058
+ new StaleWhileRevalidate({
1059
+ cacheName: 'static-resources',
1060
+ })
1061
+ );
1062
+ ```
1063
+
1064
+ ### CDN Edge Caching
1065
+
1066
+ **Cloudflare configuration:**
1067
+ ```javascript
1068
+ // Cloudflare Worker for edge caching
1069
+ addEventListener('fetch', event => {
1070
+ event.respondWith(handleRequest(event.request));
1071
+ });
1072
+
1073
+ async function handleRequest(request) {
1074
+ const cache = caches.default;
1075
+ let response = await cache.match(request);
1076
+
1077
+ if (!response) {
1078
+ response = await fetch(request);
1079
+
1080
+ // Cache for 1 hour if successful
1081
+ if (response.ok) {
1082
+ const headers = new Headers(response.headers);
1083
+ headers.set('Cache-Control', 'public, max-age=3600');
1084
+ response = new Response(response.body, {
1085
+ status: response.status,
1086
+ statusText: response.statusText,
1087
+ headers
1088
+ });
1089
+ event.waitUntil(cache.put(request, response.clone()));
1090
+ }
1091
+ }
1092
+
1093
+ return response;
1094
+ }
1095
+ ```
1096
+
1097
+ ## Framework-Specific Optimizations
1098
+
1099
+ ### Next.js
1100
+
1101
+ ```jsx
1102
+ // next.config.js
1103
+ module.exports = {
1104
+ // Image optimization
1105
+ images: {
1106
+ formats: ['image/avif', 'image/webp'],
1107
+ deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
1108
+ imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
1109
+ },
1110
+
1111
+ // Font optimization
1112
+ optimizeFonts: true,
1113
+
1114
+ // Script optimization
1115
+ swcMinify: true,
1116
+
1117
+ // Compression
1118
+ compress: true,
1119
+
1120
+ // Generate static pages
1121
+ output: 'standalone',
1122
+ };
1123
+
1124
+ // Using Next.js Image component
1125
+ import Image from 'next/image';
1126
+
1127
+ export default function Hero() {
1128
+ return (
1129
+ <Image
1130
+ src="/hero.jpg"
1131
+ alt="Hero image"
1132
+ width={1200}
1133
+ height={600}
1134
+ priority // Preload LCP image
1135
+ quality={85}
1136
+ />
1137
+ );
1138
+ }
1139
+
1140
+ // Font optimization with next/font
1141
+ import { Inter } from 'next/font/google';
1142
+
1143
+ const inter = Inter({
1144
+ subsets: ['latin'],
1145
+ display: 'swap',
1146
+ variable: '--font-inter'
1147
+ });
1148
+
1149
+ export default function RootLayout({ children }) {
1150
+ return (
1151
+ <html lang="en" className={inter.variable}>
1152
+ <body>{children}</body>
1153
+ </html>
1154
+ );
1155
+ }
1156
+
1157
+ // Static generation for performance
1158
+ export async function generateStaticParams() {
1159
+ const posts = await getPosts();
1160
+ return posts.map(post => ({ slug: post.slug }));
1161
+ }
1162
+
1163
+ // Streaming SSR with Suspense
1164
+ import { Suspense } from 'react';
1165
+
1166
+ export default function Page() {
1167
+ return (
1168
+ <>
1169
+ <Header />
1170
+ <Suspense fallback={<Skeleton />}>
1171
+ <DynamicContent />
1172
+ </Suspense>
1173
+ <Footer />
1174
+ </>
1175
+ );
1176
+ }
1177
+ ```
1178
+
1179
+ ### React
1180
+
1181
+ ```jsx
1182
+ // Component memoization
1183
+ import { memo, useMemo, useCallback } from 'react';
1184
+
1185
+ const ExpensiveComponent = memo(({ data }) => {
1186
+ const processedData = useMemo(() => {
1187
+ return data.map(item => expensiveOperation(item));
1188
+ }, [data]);
1189
+
1190
+ const handleClick = useCallback(() => {
1191
+ // Handle click
1192
+ }, []);
1193
+
1194
+ return <div onClick={handleClick}>{processedData}</div>;
1195
+ });
1196
+
1197
+ // Code splitting with React.lazy
1198
+ import { lazy, Suspense } from 'react';
1199
+
1200
+ const Dashboard = lazy(() => import('./Dashboard'));
1201
+ const Settings = lazy(() => import('./Settings'));
1202
+
1203
+ function App() {
1204
+ return (
1205
+ <Suspense fallback={<LoadingSpinner />}>
1206
+ <Routes>
1207
+ <Route path="/dashboard" element={<Dashboard />} />
1208
+ <Route path="/settings" element={<Settings />} />
1209
+ </Routes>
1210
+ </Suspense>
1211
+ );
1212
+ }
1213
+
1214
+ // Virtual scrolling for large lists
1215
+ import { FixedSizeList } from 'react-window';
1216
+
1217
+ function VirtualList({ items }) {
1218
+ return (
1219
+ <FixedSizeList
1220
+ height={600}
1221
+ itemCount={items.length}
1222
+ itemSize={80}
1223
+ width="100%"
1224
+ >
1225
+ {({ index, style }) => (
1226
+ <div style={style}>{items[index].name}</div>
1227
+ )}
1228
+ </FixedSizeList>
1229
+ );
1230
+ }
1231
+
1232
+ // React 18 transitions for better INP
1233
+ import { useTransition } from 'react';
1234
+
1235
+ function SearchComponent() {
1236
+ const [isPending, startTransition] = useTransition();
1237
+ const [query, setQuery] = useState('');
1238
+
1239
+ const handleSearch = (e) => {
1240
+ const value = e.target.value;
1241
+ setQuery(value);
1242
+
1243
+ startTransition(() => {
1244
+ // This update is marked as non-urgent
1245
+ setSearchResults(performExpensiveSearch(value));
1246
+ });
1247
+ };
1248
+
1249
+ return (
1250
+ <>
1251
+ <input value={query} onChange={handleSearch} />
1252
+ {isPending && <Spinner />}
1253
+ <Results />
1254
+ </>
1255
+ );
1256
+ }
1257
+ ```
1258
+
1259
+ ### Vue
1260
+
1261
+ ```vue
1262
+ <!-- Async components -->
1263
+ <script>
1264
+ import { defineAsyncComponent } from 'vue';
1265
+
1266
+ export default {
1267
+ components: {
1268
+ HeavyComponent: defineAsyncComponent(() =>
1269
+ import('./HeavyComponent.vue')
1270
+ )
1271
+ }
1272
+ };
1273
+ </script>
1274
+
1275
+ <!-- Keep-alive for component caching -->
1276
+ <template>
1277
+ <keep-alive :max="10">
1278
+ <component :is="currentView" />
1279
+ </keep-alive>
1280
+ </template>
1281
+
1282
+ <!-- Virtual scrolling -->
1283
+ <script setup>
1284
+ import { VirtualScroller } from 'vue-virtual-scroller';
1285
+
1286
+ const items = ref([/* thousands of items */]);
1287
+ </script>
1288
+
1289
+ <template>
1290
+ <VirtualScroller
1291
+ :items="items"
1292
+ :item-height="80"
1293
+ key-field="id"
1294
+ >
1295
+ <template #default="{ item }">
1296
+ <div>{{ item.name }}</div>
1297
+ </template>
1298
+ </VirtualScroller>
1299
+ </template>
1300
+
1301
+ <!-- Vue 3 performance optimizations -->
1302
+ <script setup>
1303
+ import { computed, watchEffect } from 'vue';
1304
+
1305
+ // Computed values are cached
1306
+ const filteredItems = computed(() => {
1307
+ return items.value.filter(item => item.active);
1308
+ });
1309
+
1310
+ // Use v-memo for expensive renders
1311
+ </script>
1312
+
1313
+ <template>
1314
+ <div v-for="item in list" :key="item.id" v-memo="[item.id, item.selected]">
1315
+ <ExpensiveComponent :item="item" />
1316
+ </div>
1317
+ </template>
1318
+ ```
1319
+
1320
+ ### Vite
1321
+
1322
+ ```javascript
1323
+ // vite.config.js
1324
+ import { defineConfig } from 'vite';
1325
+
1326
+ export default defineConfig({
1327
+ build: {
1328
+ // Manual chunk splitting (70% faster builds)
1329
+ rollupOptions: {
1330
+ output: {
1331
+ manualChunks: {
1332
+ 'vendor': ['react', 'react-dom'],
1333
+ 'ui': ['@mui/material', '@mui/icons-material'],
1334
+ 'utils': ['lodash-es', 'date-fns']
1335
+ }
1336
+ }
1337
+ },
1338
+
1339
+ // Minification
1340
+ minify: 'terser',
1341
+ terserOptions: {
1342
+ compress: {
1343
+ drop_console: true,
1344
+ drop_debugger: true
1345
+ }
1346
+ },
1347
+
1348
+ // CSS code splitting
1349
+ cssCodeSplit: true,
1350
+
1351
+ // Source maps only for development
1352
+ sourcemap: process.env.NODE_ENV === 'development'
1353
+ },
1354
+
1355
+ // Dependency pre-bundling
1356
+ optimizeDeps: {
1357
+ include: ['react', 'react-dom', 'lodash-es']
1358
+ },
1359
+
1360
+ // Development optimizations
1361
+ server: {
1362
+ hmr: {
1363
+ overlay: true
1364
+ }
1365
+ }
1366
+ });
1367
+ ```
1368
+
1369
+ ## Modern Performance Patterns (2024)
1370
+
1371
+ ### Streaming SSR
1372
+
1373
+ ```jsx
1374
+ // React 18 streaming with Suspense
1375
+ import { Suspense } from 'react';
1376
+ import { renderToReadableStream } from 'react-dom/server';
1377
+
1378
+ async function handler(req, res) {
1379
+ const stream = await renderToReadableStream(
1380
+ <App />,
1381
+ {
1382
+ onError(error) {
1383
+ console.error(error);
1384
+ }
1385
+ }
1386
+ );
1387
+
1388
+ res.setHeader('Content-Type', 'text/html');
1389
+ stream.pipeTo(new WritableStream({
1390
+ write(chunk) {
1391
+ res.write(chunk);
1392
+ },
1393
+ close() {
1394
+ res.end();
1395
+ }
1396
+ }));
1397
+ }
1398
+
1399
+ // Component with streaming
1400
+ function App() {
1401
+ return (
1402
+ <html>
1403
+ <body>
1404
+ <Header />
1405
+ <Suspense fallback={<Spinner />}>
1406
+ <Comments /> {/* Streams in when ready */}
1407
+ </Suspense>
1408
+ <Footer />
1409
+ </body>
1410
+ </html>
1411
+ );
1412
+ }
1413
+ ```
1414
+
1415
+ ### Islands Architecture
1416
+
1417
+ **Astro example:**
1418
+ ```astro
1419
+ ---
1420
+ // Static content by default
1421
+ import Header from '../components/Header.astro';
1422
+ import InteractiveWidget from '../components/InteractiveWidget.jsx';
1423
+ ---
1424
+
1425
+ <html>
1426
+ <body>
1427
+ <Header />
1428
+
1429
+ <!-- Static content -->
1430
+ <article>
1431
+ <h1>Blog Post</h1>
1432
+ <p>Static content...</p>
1433
+ </article>
1434
+
1435
+ <!-- Interactive island: only this hydrates -->
1436
+ <InteractiveWidget client:visible />
1437
+
1438
+ <footer>Static footer</footer>
1439
+ </body>
1440
+ </html>
1441
+ ```
1442
+
1443
+ **Hydration strategies:**
1444
+ ```astro
1445
+ <!-- Load immediately -->
1446
+ <Component client:load />
1447
+
1448
+ <!-- Load when idle -->
1449
+ <Component client:idle />
1450
+
1451
+ <!-- Load when visible -->
1452
+ <Component client:visible />
1453
+
1454
+ <!-- Load on media query -->
1455
+ <Component client:media="(max-width: 768px)" />
1456
+
1457
+ <!-- Only render server-side (no JS) -->
1458
+ <Component />
1459
+ ```
1460
+
1461
+ ### Progressive Hydration
1462
+
1463
+ ```jsx
1464
+ // Progressive hydration with react-lazy-hydration
1465
+ import { LazyHydrate } from 'react-lazy-hydration';
1466
+
1467
+ function App() {
1468
+ return (
1469
+ <>
1470
+ <Header />
1471
+
1472
+ {/* Hydrate immediately */}
1473
+ <HeroSection />
1474
+
1475
+ {/* Hydrate when visible */}
1476
+ <LazyHydrate whenVisible>
1477
+ <CommentsSection />
1478
+ </LazyHydrate>
1479
+
1480
+ {/* Hydrate when idle */}
1481
+ <LazyHydrate whenIdle>
1482
+ <RelatedArticles />
1483
+ </LazyHydrate>
1484
+
1485
+ {/* Hydrate on interaction */}
1486
+ <LazyHydrate on:click>
1487
+ <ShareButtons />
1488
+ </LazyHydrate>
1489
+ </>
1490
+ );
1491
+ }
1492
+ ```
1493
+
1494
+ ## Performance Monitoring
1495
+
1496
+ ### Lighthouse CI
1497
+
1498
+ ```yaml
1499
+ # .github/workflows/lighthouse.yml
1500
+ name: Lighthouse CI
1501
+ on: [push, pull_request]
1502
+
1503
+ jobs:
1504
+ lighthouse:
1505
+ runs-on: ubuntu-latest
1506
+ steps:
1507
+ - uses: actions/checkout@v3
1508
+ - name: Install dependencies
1509
+ run: npm ci
1510
+ - name: Build
1511
+ run: npm run build
1512
+ - name: Run Lighthouse CI
1513
+ uses: treosh/lighthouse-ci-action@v10
1514
+ with:
1515
+ urls: |
1516
+ http://localhost:3000
1517
+ http://localhost:3000/about
1518
+ uploadArtifacts: true
1519
+ temporaryPublicStorage: true
1520
+ ```
1521
+
1522
+ **lighthouserc.json:**
1523
+ ```json
1524
+ {
1525
+ "ci": {
1526
+ "collect": {
1527
+ "numberOfRuns": 3,
1528
+ "startServerCommand": "npm run serve",
1529
+ "url": ["http://localhost:3000/"]
1530
+ },
1531
+ "assert": {
1532
+ "assertions": {
1533
+ "categories:performance": ["error", {"minScore": 0.9}],
1534
+ "categories:accessibility": ["error", {"minScore": 0.9}],
1535
+ "first-contentful-paint": ["error", {"maxNumericValue": 2000}],
1536
+ "largest-contentful-paint": ["error", {"maxNumericValue": 2500}],
1537
+ "cumulative-layout-shift": ["error", {"maxNumericValue": 0.1}],
1538
+ "total-blocking-time": ["error", {"maxNumericValue": 300}]
1539
+ }
1540
+ },
1541
+ "upload": {
1542
+ "target": "temporary-public-storage"
1543
+ }
1544
+ }
1545
+ }
1546
+ ```
1547
+
1548
+ ### Performance Budgets
1549
+
1550
+ ```json
1551
+ // budget.json
1552
+ [
1553
+ {
1554
+ "resourceSizes": [
1555
+ {
1556
+ "resourceType": "document",
1557
+ "budget": 50
1558
+ },
1559
+ {
1560
+ "resourceType": "script",
1561
+ "budget": 300
1562
+ },
1563
+ {
1564
+ "resourceType": "stylesheet",
1565
+ "budget": 50
1566
+ },
1567
+ {
1568
+ "resourceType": "image",
1569
+ "budget": 500
1570
+ },
1571
+ {
1572
+ "resourceType": "font",
1573
+ "budget": 100
1574
+ },
1575
+ {
1576
+ "resourceType": "total",
1577
+ "budget": 1000
1578
+ }
1579
+ ],
1580
+ "resourceCounts": [
1581
+ {
1582
+ "resourceType": "third-party",
1583
+ "budget": 10
1584
+ }
1585
+ ]
1586
+ }
1587
+ ]
1588
+ ```
1589
+
1590
+ **Webpack bundle size budget:**
1591
+ ```javascript
1592
+ // webpack.config.js
1593
+ module.exports = {
1594
+ performance: {
1595
+ maxAssetSize: 300000, // 300KB
1596
+ maxEntrypointSize: 500000, // 500KB
1597
+ hints: 'error'
1598
+ }
1599
+ };
1600
+ ```
1601
+
1602
+ ### Real User Monitoring (RUM)
1603
+
1604
+ ```javascript
1605
+ // Using web-vitals library
1606
+ import { onCLS, onFCP, onINP, onLCP, onTTFB } from 'web-vitals';
1607
+
1608
+ function sendToAnalytics(metric) {
1609
+ const body = JSON.stringify({
1610
+ name: metric.name,
1611
+ value: metric.value,
1612
+ rating: metric.rating,
1613
+ delta: metric.delta,
1614
+ id: metric.id,
1615
+ navigationType: metric.navigationType
1616
+ });
1617
+
1618
+ // Use sendBeacon for reliable delivery
1619
+ if (navigator.sendBeacon) {
1620
+ navigator.sendBeacon('/analytics', body);
1621
+ } else {
1622
+ fetch('/analytics', { body, method: 'POST', keepalive: true });
1623
+ }
1624
+ }
1625
+
1626
+ // Measure all Core Web Vitals
1627
+ onCLS(sendToAnalytics);
1628
+ onFCP(sendToAnalytics);
1629
+ onINP(sendToAnalytics);
1630
+ onLCP(sendToAnalytics);
1631
+ onTTFB(sendToAnalytics);
1632
+
1633
+ // Attribution for debugging
1634
+ import { onLCP } from 'web-vitals/attribution';
1635
+
1636
+ onLCP((metric) => {
1637
+ console.log('LCP element:', metric.attribution.element);
1638
+ console.log('LCP resource:', metric.attribution.url);
1639
+ console.log('LCP time:', metric.value);
1640
+ sendToAnalytics(metric);
1641
+ });
1642
+ ```
1643
+
1644
+ **RUM vs Lab Data:**
1645
+ - Lab data (Lighthouse): Controlled environment, consistent results
1646
+ - RUM: Real user conditions, network variability, device diversity
1647
+ - Use both: Lab for development, RUM for production monitoring
1648
+
1649
+ ### Chrome DevTools Performance Panel
1650
+
1651
+ **2024 updates:**
1652
+ - Live Core Web Vitals overlay
1653
+ - INP debugging (replaced FID)
1654
+ - Enhanced flame chart
1655
+ - Interaction tracking
1656
+
1657
+ **Workflow:**
1658
+ 1. Open DevTools (F12) → Performance tab
1659
+ 2. Click Record, interact with page, stop recording
1660
+ 3. Analyze:
1661
+ - Main thread activity (find long tasks)
1662
+ - Network waterfall (identify bottlenecks)
1663
+ - Core Web Vitals annotations
1664
+ - Frame rate drops
1665
+ 4. Use bottom-up view to identify expensive functions
1666
+
1667
+ ## Common Performance Issues
1668
+
1669
+ ### Issue 1: Unoptimized Images
1670
+
1671
+ **Impact:** 73% of sites have image LCP
1672
+
1673
+ **Symptoms:**
1674
+ - Slow LCP (>2.5s)
1675
+ - High bandwidth usage
1676
+ - Large LCP element in Lighthouse
1677
+
1678
+ **Solution:**
1679
+
1680
+ 1. **Convert to modern formats:**
1681
+ ```bash
1682
+ # Using ImageMagick
1683
+ magick input.jpg -quality 85 output.webp
1684
+ magick input.jpg -quality 85 output.avif
1685
+
1686
+ # Using cwebp/cavif
1687
+ cwebp -q 85 input.jpg -o output.webp
1688
+ avifenc -s 5 input.jpg output.avif
1689
+ ```
1690
+
1691
+ 2. **Implement responsive images:**
1692
+ ```html
1693
+ <picture>
1694
+ <source
1695
+ srcset="hero-400.avif 400w, hero-800.avif 800w, hero-1200.avif 1200w"
1696
+ type="image/avif"
1697
+ >
1698
+ <source
1699
+ srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
1700
+ type="image/webp"
1701
+ >
1702
+ <img
1703
+ srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
1704
+ sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
1705
+ src="hero-800.jpg"
1706
+ alt="Hero image"
1707
+ fetchpriority="high"
1708
+ >
1709
+ </picture>
1710
+ ```
1711
+
1712
+ 3. **Use image CDN:**
1713
+ ```javascript
1714
+ // Cloudinary automatic optimization
1715
+ const imageUrl = cloudinary.url('hero.jpg', {
1716
+ fetch_format: 'auto',
1717
+ quality: 'auto',
1718
+ width: 'auto',
1719
+ dpr: 'auto',
1720
+ crop: 'scale'
1721
+ });
1722
+ ```
1723
+
1724
+ ### Issue 2: Render-Blocking Resources
1725
+
1726
+ **Impact:** Delays FCP/LCP by seconds
1727
+
1728
+ **Symptoms:**
1729
+ - "Eliminate render-blocking resources" in Lighthouse
1730
+ - Long white screen time
1731
+ - Delayed FCP
1732
+
1733
+ **Solution:**
1734
+
1735
+ 1. **Inline critical CSS:**
1736
+ ```html
1737
+ <head>
1738
+ <style>
1739
+ /* Critical above-the-fold CSS */
1740
+ body { margin: 0; font-family: system-ui; }
1741
+ .hero { height: 100vh; background: #f0f0f0; }
1742
+ </style>
1743
+
1744
+ <!-- Defer non-critical CSS -->
1745
+ <link rel="preload" as="style" href="main.css" onload="this.onload=null;this.rel='stylesheet'">
1746
+ <noscript><link rel="stylesheet" href="main.css"></noscript>
1747
+ </head>
1748
+ ```
1749
+
1750
+ 2. **Defer JavaScript:**
1751
+ ```html
1752
+ <!-- Defer non-critical scripts -->
1753
+ <script src="main.js" defer></script>
1754
+
1755
+ <!-- Async for independent scripts -->
1756
+ <script src="analytics.js" async></script>
1757
+
1758
+ <!-- Module scripts are deferred by default -->
1759
+ <script type="module" src="app.js"></script>
1760
+ ```
1761
+
1762
+ 3. **Remove unused CSS:**
1763
+ ```bash
1764
+ # Using PurgeCSS
1765
+ npm install --save-dev @fullhuman/postcss-purgecss
1766
+ ```
1767
+
1768
+ ### Issue 3: Third-Party Script Bloat
1769
+
1770
+ **Impact:** 90%+ sites affected, major contributor to TBT
1771
+
1772
+ **Symptoms:**
1773
+ - High TBT (>200ms)
1774
+ - "Reduce JavaScript execution time" in Lighthouse
1775
+ - Slow INP
1776
+
1777
+ **Solution:**
1778
+
1779
+ 1. **Audit third-party scripts:**
1780
+ ```javascript
1781
+ // Find third-party impact in DevTools
1782
+ // Coverage tab → Show third-party badges
1783
+
1784
+ // Performance Insights → Third-party usage
1785
+ ```
1786
+
1787
+ 2. **Lazy load non-critical scripts:**
1788
+ ```javascript
1789
+ // Load on interaction
1790
+ let analyticsLoaded = false;
1791
+
1792
+ function loadAnalytics() {
1793
+ if (analyticsLoaded) return;
1794
+ analyticsLoaded = true;
1795
+
1796
+ const script = document.createElement('script');
1797
+ script.src = 'https://analytics.example.com/script.js';
1798
+ document.head.appendChild(script);
1799
+ }
1800
+
1801
+ ['click', 'scroll', 'keydown'].forEach(event => {
1802
+ window.addEventListener(event, loadAnalytics, { once: true });
1803
+ });
1804
+
1805
+ setTimeout(loadAnalytics, 5000); // Fallback
1806
+ ```
1807
+
1808
+ 3. **Use facades for heavy embeds:**
1809
+ ```javascript
1810
+ // YouTube facade (save ~500KB)
1811
+ class YoutubeFacade extends HTMLElement {
1812
+ connectedCallback() {
1813
+ const videoId = this.getAttribute('videoid');
1814
+ this.innerHTML = `
1815
+ <div class="facade" style="cursor: pointer;">
1816
+ <img src="https://i.ytimg.com/vi/${videoId}/hqdefault.jpg">
1817
+ <button class="play-button">▶</button>
1818
+ </div>
1819
+ `;
1820
+
1821
+ this.querySelector('.facade').addEventListener('click', () => {
1822
+ this.innerHTML = `
1823
+ <iframe
1824
+ src="https://www.youtube.com/embed/${videoId}?autoplay=1"
1825
+ allow="autoplay"
1826
+ allowfullscreen
1827
+ ></iframe>
1828
+ `;
1829
+ });
1830
+ }
1831
+ }
1832
+
1833
+ customElements.define('youtube-facade', YoutubeFacade);
1834
+ ```
1835
+
1836
+ ### Issue 4: Layout Shifts
1837
+
1838
+ **Impact:** Poor CLS score (>0.1)
1839
+
1840
+ **Symptoms:**
1841
+ - Content jumping during load
1842
+ - "Avoid large layout shifts" in Lighthouse
1843
+ - Elements moving unexpectedly
1844
+
1845
+ **Solution:**
1846
+
1847
+ 1. **Reserve space for images:**
1848
+ ```html
1849
+ <!-- Always include dimensions -->
1850
+ <img src="photo.jpg" width="800" height="600" alt="Photo">
1851
+
1852
+ <!-- Or use aspect-ratio -->
1853
+ <style>
1854
+ .image-container {
1855
+ aspect-ratio: 16 / 9;
1856
+ }
1857
+ .image-container img {
1858
+ width: 100%;
1859
+ height: 100%;
1860
+ object-fit: cover;
1861
+ }
1862
+ </style>
1863
+ ```
1864
+
1865
+ 2. **Prevent font layout shifts:**
1866
+ ```css
1867
+ /* Use font-display: optional for best CLS */
1868
+ @font-face {
1869
+ font-family: 'Main Font';
1870
+ src: url('/fonts/main.woff2') format('woff2');
1871
+ font-display: optional; /* Prevents FOIT and minimizes shift */
1872
+ }
1873
+
1874
+ /* Or use fallback font metrics matching */
1875
+ @font-face {
1876
+ font-family: 'Main Font Fallback';
1877
+ src: local('Arial');
1878
+ ascent-override: 95%;
1879
+ descent-override: 25%;
1880
+ line-gap-override: 0%;
1881
+ size-adjust: 100%;
1882
+ }
1883
+
1884
+ body {
1885
+ font-family: 'Main Font', 'Main Font Fallback', sans-serif;
1886
+ }
1887
+ ```
1888
+
1889
+ 3. **Use skeleton screens:**
1890
+ ```css
1891
+ .skeleton {
1892
+ background: linear-gradient(
1893
+ 90deg,
1894
+ #f0f0f0 25%,
1895
+ #e0e0e0 50%,
1896
+ #f0f0f0 75%
1897
+ );
1898
+ background-size: 200% 100%;
1899
+ animation: loading 1.5s infinite;
1900
+ min-height: 200px;
1901
+ }
1902
+
1903
+ @keyframes loading {
1904
+ 0% { background-position: 200% 0; }
1905
+ 100% { background-position: -200% 0; }
1906
+ }
1907
+ ```
1908
+
1909
+ ### Issue 5: Large JavaScript Bundles
1910
+
1911
+ **Impact:** Slow TTI, high TBT (>200ms)
1912
+
1913
+ **Symptoms:**
1914
+ - "Reduce JavaScript execution time" in Lighthouse
1915
+ - Large bundle sizes (>300KB)
1916
+ - Slow initial load
1917
+
1918
+ **Solution:**
1919
+
1920
+ 1. **Analyze bundle:**
1921
+ ```bash
1922
+ # webpack-bundle-analyzer
1923
+ npm install --save-dev webpack-bundle-analyzer
1924
+ npm run build -- --analyze
1925
+ ```
1926
+
1927
+ 2. **Code splitting:**
1928
+ ```javascript
1929
+ // Route-based splitting
1930
+ const Home = lazy(() => import('./pages/Home'));
1931
+ const Dashboard = lazy(() => import('./pages/Dashboard'));
1932
+
1933
+ // Component-based splitting
1934
+ const Chart = lazy(() => import('./components/Chart'));
1935
+
1936
+ // Vendor splitting
1937
+ // webpack.config.js
1938
+ optimization: {
1939
+ splitChunks: {
1940
+ chunks: 'all',
1941
+ cacheGroups: {
1942
+ vendor: {
1943
+ test: /[\\/]node_modules[\\/]/,
1944
+ name: 'vendors',
1945
+ priority: 10
1946
+ }
1947
+ }
1948
+ }
1949
+ }
1950
+ ```
1951
+
1952
+ 3. **Tree shaking:**
1953
+ ```javascript
1954
+ // Import only what you need
1955
+ import { debounce } from 'lodash-es'; // Good
1956
+ import debounce from 'lodash/debounce'; // Good
1957
+ import _ from 'lodash'; // Bad: imports entire library
1958
+ ```
1959
+
1960
+ ### Issue 6: Poor Font Loading
1961
+
1962
+ **Impact:** FOIT/FOUT, layout shifts, delayed FCP
1963
+
1964
+ **Symptoms:**
1965
+ - Invisible text during load (FOIT)
1966
+ - Flash of unstyled text (FOUT)
1967
+ - Layout shifts when font loads
1968
+
1969
+ **Solution:**
1970
+
1971
+ 1. **Preload critical fonts:**
1972
+ ```html
1973
+ <link rel="preload" as="font" type="font/woff2" href="/fonts/main.woff2" crossorigin>
1974
+ ```
1975
+
1976
+ 2. **Optimize font-display:**
1977
+ ```css
1978
+ @font-face {
1979
+ font-family: 'Main Font';
1980
+ src: url('/fonts/main.woff2') format('woff2');
1981
+ font-display: optional; /* Best for CLS */
1982
+ /* font-display: swap; Prevents FOIT but may cause shift */
1983
+ }
1984
+ ```
1985
+
1986
+ 3. **Subset fonts:**
1987
+ ```bash
1988
+ # Using pyftsubset (fonttools)
1989
+ pyftsubset font.ttf \
1990
+ --output-file=font-subset.woff2 \
1991
+ --flavor=woff2 \
1992
+ --unicodes="U+0020-007E" # ASCII characters
1993
+ ```
1994
+
1995
+ 4. **Use system fonts:**
1996
+ ```css
1997
+ body {
1998
+ font-family:
1999
+ -apple-system,
2000
+ BlinkMacSystemFont,
2001
+ 'Segoe UI',
2002
+ Roboto,
2003
+ 'Helvetica Neue',
2004
+ Arial,
2005
+ sans-serif;
2006
+ }
2007
+ ```
2008
+
2009
+ ## Performance Audit Workflow
2010
+
2011
+ ### 1. Baseline Measurement
2012
+
2013
+ **Run Lighthouse:**
2014
+ ```bash
2015
+ lighthouse https://example.com --view --output html json --output-path ./report
2016
+ ```
2017
+
2018
+ **Run WebPageTest:**
2019
+ - Visit webpagetest.org
2020
+ - Enter URL, select location and device
2021
+ - Run test 3 times for median results
2022
+
2023
+ **Collect field data:**
2024
+ ```javascript
2025
+ // Chrome User Experience Report (CrUX) via PageSpeed Insights API
2026
+ const url = 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed';
2027
+ const params = `?url=https://example.com&key=YOUR_API_KEY`;
2028
+
2029
+ fetch(url + params)
2030
+ .then(res => res.json())
2031
+ .then(data => {
2032
+ console.log('Field data:', data.loadingExperience.metrics);
2033
+ });
2034
+ ```
2035
+
2036
+ ### 2. Identify Bottlenecks
2037
+
2038
+ **Priority order:**
2039
+ 1. LCP issues (25% weight) - Images, fonts, server response
2040
+ 2. TBT issues (30% weight) - JavaScript execution, long tasks
2041
+ 3. CLS issues (25% weight) - Images without dimensions, fonts, dynamic content
2042
+ 4. FCP issues (10% weight) - Render-blocking resources
2043
+ 5. Other metrics (10% weight)
2044
+
2045
+ ### 3. Implement Optimizations
2046
+
2047
+ **High-impact changes first:**
2048
+ 1. Optimize LCP image (modern format, CDN, preload)
2049
+ 2. Reduce JavaScript (code splitting, remove unused code)
2050
+ 3. Fix layout shifts (reserve space, font-display)
2051
+ 4. Eliminate render-blocking resources (defer, async, inline critical)
2052
+ 5. Optimize third-party scripts (lazy load, facades)
2053
+
2054
+ ### 4. Measure Impact
2055
+
2056
+ **Before/after comparison:**
2057
+ ```javascript
2058
+ // Track metrics over time
2059
+ const metrics = {
2060
+ before: {
2061
+ LCP: 3200,
2062
+ INP: 450,
2063
+ CLS: 0.18,
2064
+ TBT: 580,
2065
+ score: 62
2066
+ },
2067
+ after: {
2068
+ LCP: 2100, // 34% improvement
2069
+ INP: 180, // 60% improvement
2070
+ CLS: 0.05, // 72% improvement
2071
+ TBT: 150, // 74% improvement
2072
+ score: 94 // 52% improvement
2073
+ }
2074
+ };
2075
+ ```
2076
+
2077
+ ### 5. Set Up Monitoring
2078
+
2079
+ **Lighthouse CI:**
2080
+ ```yaml
2081
+ # .github/workflows/lighthouse.yml
2082
+ - name: Run Lighthouse CI
2083
+ uses: treosh/lighthouse-ci-action@v10
2084
+ ```
2085
+
2086
+ **Real User Monitoring:**
2087
+ ```javascript
2088
+ import { onCLS, onFCP, onINP, onLCP } from 'web-vitals';
2089
+
2090
+ [onCLS, onFCP, onINP, onLCP].forEach(fn => fn(sendToAnalytics));
2091
+ ```
2092
+
2093
+ ## Performance Budget Template
2094
+
2095
+ ```json
2096
+ {
2097
+ "performance": {
2098
+ "score": 90,
2099
+ "metrics": {
2100
+ "first-contentful-paint": 1800,
2101
+ "largest-contentful-paint": 2500,
2102
+ "interaction-to-next-paint": 200,
2103
+ "cumulative-layout-shift": 0.1,
2104
+ "total-blocking-time": 200,
2105
+ "speed-index": 3000
2106
+ }
2107
+ },
2108
+ "resourceSizes": {
2109
+ "document": 50,
2110
+ "script": 300,
2111
+ "stylesheet": 50,
2112
+ "image": 500,
2113
+ "font": 100,
2114
+ "total": 1000
2115
+ },
2116
+ "resourceCounts": {
2117
+ "third-party": 10,
2118
+ "total": 50
2119
+ }
2120
+ }
2121
+ ```
2122
+
2123
+ ## Business Impact
2124
+
2125
+ ### Conversion Impact
2126
+
2127
+ - **1 second delay = 7% conversion loss** (Amazon)
2128
+ - **0.1s improvement = 8% increase in conversions** (Walmart)
2129
+ - **3s load time = 32% abandon rate** (Google)
2130
+ - **53% mobile users abandon after 3s** (Google)
2131
+ - **Page speed is a ranking factor** (Google)
2132
+
2133
+ **Case Studies:**
2134
+
2135
+ - **Pinterest:** Reduced perceived wait times by 40%, increased SEO traffic by 15%, increased sign-ups by 15%
2136
+ - **Zalando:** 0.1s improvement = 0.7% increase in revenue
2137
+ - **AutoAnything:** 50% faster page load = 12-13% increase in sales
2138
+ - **BBC:** Lost 10% of users for every additional second of load time
2139
+
2140
+ ### SEO Impact
2141
+
2142
+ - **Core Web Vitals as ranking factor** (June 2021+)
2143
+ - **Page experience signals** affect rankings
2144
+ - **Mobile-first indexing** prioritizes mobile performance
2145
+ - **75% of users pass Core Web Vitals = ranking boost**
2146
+
2147
+ ## Quick Reference
2148
+
2149
+ ### Commands
2150
+
2151
+ ```bash
2152
+ # Lighthouse CLI
2153
+ lighthouse https://example.com --view
2154
+
2155
+ # Lighthouse CI
2156
+ lhci autorun
2157
+
2158
+ # WebPageTest CLI
2159
+ webpagetest test https://example.com --key YOUR_KEY
2160
+
2161
+ # Chrome DevTools headless
2162
+ chrome --headless --disable-gpu --screenshot https://example.com
2163
+
2164
+ # Image optimization
2165
+ cwebp -q 85 input.jpg -o output.webp
2166
+ avifenc -s 5 input.jpg output.avif
2167
+
2168
+ # Bundle analysis
2169
+ webpack-bundle-analyzer dist/stats.json
2170
+ ```
2171
+
2172
+ ### Optimization Checklist
2173
+
2174
+ **Images:**
2175
+ - [ ] Convert to WebP/AVIF
2176
+ - [ ] Implement responsive images with srcset
2177
+ - [ ] Add width/height attributes
2178
+ - [ ] Lazy load below-fold images
2179
+ - [ ] Preload LCP image with fetchpriority="high"
2180
+ - [ ] Use CDN with automatic optimization
2181
+
2182
+ **JavaScript:**
2183
+ - [ ] Code splitting (route-based and component-based)
2184
+ - [ ] Tree shaking enabled
2185
+ - [ ] Remove unused code
2186
+ - [ ] Defer non-critical scripts
2187
+ - [ ] Lazy load third-party scripts
2188
+ - [ ] Use web workers for heavy computations
2189
+
2190
+ **CSS:**
2191
+ - [ ] Extract and inline critical CSS
2192
+ - [ ] Remove unused CSS (PurgeCSS)
2193
+ - [ ] Defer non-critical CSS
2194
+ - [ ] Minify CSS
2195
+ - [ ] Use modern CSS features (containment, content-visibility)
2196
+
2197
+ **Fonts:**
2198
+ - [ ] Preload critical fonts
2199
+ - [ ] Use font-display: optional or swap
2200
+ - [ ] Subset fonts
2201
+ - [ ] Consider system fonts
2202
+
2203
+ **Caching:**
2204
+ - [ ] Set Cache-Control headers
2205
+ - [ ] Implement service worker
2206
+ - [ ] Use CDN edge caching
2207
+ - [ ] Enable stale-while-revalidate
2208
+
2209
+ **Server:**
2210
+ - [ ] Enable HTTP/2 or HTTP/3
2211
+ - [ ] Implement 103 Early Hints
2212
+ - [ ] Optimize TTFB (<800ms)
2213
+ - [ ] Enable compression (Brotli/gzip)
2214
+
2215
+ **Monitoring:**
2216
+ - [ ] Set up Lighthouse CI
2217
+ - [ ] Implement Real User Monitoring
2218
+ - [ ] Define performance budgets
2219
+ - [ ] Set up alerting
2220
+
2221
+ ### Tools List
2222
+
2223
+ **Measurement:**
2224
+ - Lighthouse (CLI, DevTools, CI)
2225
+ - WebPageTest
2226
+ - Chrome DevTools Performance Panel
2227
+ - PageSpeed Insights (includes CrUX data)
2228
+
2229
+ **Monitoring:**
2230
+ - web-vitals library
2231
+ - Lighthouse CI
2232
+ - SpeedCurve
2233
+ - Calibre
2234
+ - Vercel Analytics
2235
+ - Cloudflare Web Analytics
2236
+
2237
+ **Optimization:**
2238
+ - ImageMagick, cwebp, avifenc (images)
2239
+ - webpack-bundle-analyzer (bundle analysis)
2240
+ - PurgeCSS (unused CSS)
2241
+ - Critical (critical CSS extraction)
2242
+ - Workbox (service workers)
2243
+ - Partytown (third-party scripts in web workers)
2244
+
2245
+ **Testing:**
2246
+ - Lighthouse
2247
+ - Chrome DevTools
2248
+ - WebPageTest
2249
+ - GTmetrix
2250
+ - Pingdom
2251
+
2252
+ ## Anti-Patterns
2253
+
2254
+ ### What NOT to Do
2255
+
2256
+ ❌ **Loading all resources eagerly**
2257
+ - Don't load all JavaScript upfront
2258
+ - Don't load all images without lazy loading
2259
+ - Don't preload everything
2260
+
2261
+ ❌ **Ignoring image optimization**
2262
+ - Don't use unoptimized JPEGs/PNGs
2263
+ - Don't skip responsive images
2264
+ - Don't forget width/height attributes
2265
+
2266
+ ❌ **No caching strategy**
2267
+ - Don't skip Cache-Control headers
2268
+ - Don't forget service worker caching
2269
+ - Don't ignore CDN caching
2270
+
2271
+ ❌ **Blocking render with non-critical resources**
2272
+ - Don't include all CSS in head without deferring
2273
+ - Don't use synchronous scripts in head
2274
+ - Don't skip async/defer on third-party scripts
2275
+
2276
+ ❌ **Ignoring third-party script impact**
2277
+ - Don't load analytics/ads synchronously
2278
+ - Don't embed heavy widgets without facades
2279
+ - Don't skip third-party script auditing
2280
+
2281
+ ❌ **No performance monitoring**
2282
+ - Don't skip Lighthouse CI
2283
+ - Don't ignore Real User Monitoring
2284
+ - Don't forget performance budgets
2285
+
2286
+ ❌ **Optimizing without measurement**
2287
+ - Don't optimize blindly
2288
+ - Don't skip baseline measurements
2289
+ - Don't forget A/B testing
2290
+
2291
+ ❌ **Premature optimization**
2292
+ - Don't optimize before profiling
2293
+ - Don't add complexity without data
2294
+ - Don't optimize the wrong things
2295
+
2296
+ ## Related Skills
2297
+
2298
+ - **nextjs-local-dev** - Next.js-specific optimizations
2299
+ - **vite-local-dev** - Vite build optimizations
2300
+ - **docker-containerization** - Optimizing Docker images for performance
2301
+ - **systematic-debugging** - Debugging performance issues
2302
+
2303
+ ---
2304
+
2305
+ **Remember:** Performance is a feature, not an afterthought. Every millisecond counts toward user experience, conversions, and SEO. Measure, optimize, and monitor continuously.