Loading...
Loading...
Optimize website and web application performance including loading speed, Core Web Vitals, bundle size, caching strategies, and runtime performance
npx skill4agent add sickn33/antigravity-awesome-skills web-performance-optimization## Performance Audit Results
### Current Metrics (Before Optimization)
- **LCP (Largest Contentful Paint):** 4.2s ❌ (should be < 2.5s)
- **FID (First Input Delay):** 180ms ❌ (should be < 100ms)
- **CLS (Cumulative Layout Shift):** 0.25 ❌ (should be < 0.1)
- **Lighthouse Score:** 62/100
### Issues Identified
1. **LCP Issue:** Hero image (2.5MB) loads slowly
2. **FID Issue:** Large JavaScript bundle (850KB) blocks main thread
3. **CLS Issue:** Images without dimensions cause layout shifts
### Optimization Plan
#### Fix LCP (Largest Contentful Paint)
**Problem:** Hero image is 2.5MB and loads slowly
**Solutions:**
\`\`\`html
<!-- Before: Unoptimized image -->
<img src="/hero.jpg" alt="Hero">
<!-- After: Optimized with modern formats -->
<picture>
<source srcset="/hero.avif" type="image/avif">
<source srcset="/hero.webp" type="image/webp">
<img
src="/hero.jpg"
alt="Hero"
width="1200"
height="600"
loading="eager"
fetchpriority="high"
>
</picture>
\`\`\`
**Additional optimizations:**
- Compress image to < 200KB
- Use CDN for faster delivery
- Preload hero image: `<link rel="preload" as="image" href="/hero.avif">`
#### Fix FID (First Input Delay)
**Problem:** 850KB JavaScript bundle blocks main thread
**Solutions:**
1. **Code Splitting:**
\`\`\`javascript
// Before: Everything in one bundle
import { HeavyComponent } from './HeavyComponent';
import { Analytics } from './analytics';
import { ChatWidget } from './chat';
// After: Lazy load non-critical code
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const ChatWidget = lazy(() => import('./chat'));
// Load analytics after page interactive
if (typeof window !== 'undefined') {
window.addEventListener('load', () => {
import('./analytics').then(({ Analytics }) => {
Analytics.init();
});
});
}
\`\`\`
2. **Remove Unused Dependencies:**
\`\`\`bash
# Analyze bundle
npx webpack-bundle-analyzer
# Remove unused packages
npm uninstall moment # Use date-fns instead (smaller)
npm install date-fns
\`\`\`
3. **Defer Non-Critical Scripts:**
\`\`\`html
<!-- Before: Blocks rendering -->
<script src="/analytics.js"></script>
<!-- After: Deferred -->
<script src="/analytics.js" defer></script>
\`\`\`
#### Fix CLS (Cumulative Layout Shift)
**Problem:** Images without dimensions cause layout shifts
**Solutions:**
\`\`\`html
<!-- Before: No dimensions -->
<img src="/product.jpg" alt="Product">
<!-- After: With dimensions -->
<img
src="/product.jpg"
alt="Product"
width="400"
height="300"
style="aspect-ratio: 4/3;"
>
\`\`\`
**For dynamic content:**
\`\`\`css
/* Reserve space for content that loads later */
.skeleton-loader {
min-height: 200px;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
@keyframes loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
\`\`\`
### Results After Optimization
- **LCP:** 1.8s ✅ (improved by 57%)
- **FID:** 45ms ✅ (improved by 75%)
- **CLS:** 0.05 ✅ (improved by 80%)
- **Lighthouse Score:** 94/100 ✅## Bundle Size Optimization
### Current State
- **Total Bundle:** 850KB (gzipped: 280KB)
- **Main Bundle:** 650KB
- **Vendor Bundle:** 200KB
- **Load Time (3G):** 8.2s
### Analysis
\`\`\`bash
# Analyze bundle composition
npx webpack-bundle-analyzer dist/stats.json
\`\`\`
**Findings:**
1. Moment.js: 67KB (can replace with date-fns: 12KB)
2. Lodash: 72KB (using entire library, only need 5 functions)
3. Unused code: ~150KB of dead code
4. No code splitting: Everything in one bundle
### Optimization Steps
#### 1. Replace Heavy Dependencies
\`\`\`bash
# Remove moment.js (67KB) → Use date-fns (12KB)
npm uninstall moment
npm install date-fns
# Before
import moment from 'moment';
const formatted = moment(date).format('YYYY-MM-DD');
# After
import { format } from 'date-fns';
const formatted = format(date, 'yyyy-MM-dd');
\`\`\`
**Savings:** 55KB
#### 2. Use Lodash Selectively
\`\`\`javascript
// Before: Import entire library (72KB)
import _ from 'lodash';
const unique = _.uniq(array);
// After: Import only what you need (5KB)
import uniq from 'lodash/uniq';
const unique = uniq(array);
// Or use native methods
const unique = [...new Set(array)];
\`\`\`
**Savings:** 67KB
#### 3. Implement Code Splitting
\`\`\`javascript
// Next.js example
import dynamic from 'next/dynamic';
// Lazy load heavy components
const Chart = dynamic(() => import('./Chart'), {
loading: () => <div>Loading chart...</div>,
ssr: false
});
const AdminPanel = dynamic(() => import('./AdminPanel'), {
loading: () => <div>Loading...</div>
});
// Route-based code splitting (automatic in Next.js)
// pages/admin.js - Only loaded when visiting /admin
// pages/dashboard.js - Only loaded when visiting /dashboard
\`\`\`
#### 4. Remove Dead Code
\`\`\`javascript
// Enable tree shaking in webpack.config.js
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
// In package.json
{
"sideEffects": false
}
\`\`\`
#### 5. Optimize Third-Party Scripts
\`\`\`html
<!-- Before: Loads immediately -->
<script src="https://analytics.com/script.js"></script>
<!-- After: Load after page interactive -->
<script>
window.addEventListener('load', () => {
const script = document.createElement('script');
script.src = 'https://analytics.com/script.js';
script.async = true;
document.body.appendChild(script);
});
</script>
\`\`\`
### Results
- **Total Bundle:** 380KB ✅ (reduced by 55%)
- **Main Bundle:** 180KB ✅
- **Vendor Bundle:** 80KB ✅
- **Load Time (3G):** 3.1s ✅ (improved by 62%)## Image Optimization
### Current Issues
- 15 images totaling 12MB
- No modern formats (WebP, AVIF)
- No responsive images
- No lazy loading
### Optimization Strategy
#### 1. Convert to Modern Formats
\`\`\`bash
# Install image optimization tools
npm install sharp
# Conversion script (optimize-images.js)
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
async function optimizeImage(inputPath, outputDir) {
const filename = path.basename(inputPath, path.extname(inputPath));
// Generate WebP
await sharp(inputPath)
.webp({ quality: 80 })
.toFile(path.join(outputDir, \`\${filename}.webp\`));
// Generate AVIF (best compression)
await sharp(inputPath)
.avif({ quality: 70 })
.toFile(path.join(outputDir, \`\${filename}.avif\`));
// Generate optimized JPEG fallback
await sharp(inputPath)
.jpeg({ quality: 80, progressive: true })
.toFile(path.join(outputDir, \`\${filename}.jpg\`));
}
// Process all images
const images = fs.readdirSync('./images');
images.forEach(img => {
optimizeImage(\`./images/\${img}\`, './images/optimized');
});
\`\`\`
#### 2. Implement Responsive Images
\`\`\`html
<!-- Responsive images with modern formats -->
<picture>
<!-- AVIF for browsers that support it (best compression) -->
<source
srcset="
/images/hero-400.avif 400w,
/images/hero-800.avif 800w,
/images/hero-1200.avif 1200w
"
type="image/avif"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- WebP for browsers that support it -->
<source
srcset="
/images/hero-400.webp 400w,
/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w
"
type="image/webp"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- JPEG fallback -->
<img
src="/images/hero-800.jpg"
srcset="
/images/hero-400.jpg 400w,
/images/hero-800.jpg 800w,
/images/hero-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
alt="Hero image"
width="1200"
height="600"
loading="lazy"
>
</picture>
\`\`\`
#### 3. Lazy Loading
\`\`\`html
<!-- Native lazy loading -->
<img
src="/image.jpg"
alt="Description"
loading="lazy"
width="800"
height="600"
>
<!-- Eager loading for above-the-fold images -->
<img
src="/hero.jpg"
alt="Hero"
loading="eager"
fetchpriority="high"
>
\`\`\`
#### 4. Next.js Image Component
\`\`\`javascript
import Image from 'next/image';
// Automatic optimization
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // For above-the-fold images
quality={80}
/>
// Lazy loaded
<Image
src="/product.jpg"
alt="Product"
width={400}
height={300}
loading="lazy"
/>
\`\`\`
### Results
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| Total Image Size | 12MB | 1.8MB | 85% reduction |
| LCP | 4.5s | 1.6s | 64% faster |
| Page Load (3G) | 18s | 4.2s | 77% faster |<link rel="preload"># Test with throttling
lighthouse https://yoursite.com --throttling.cpuSlowdownMultiplier=4# Analyze bundle
npx webpack-bundle-analyzer dist/stats.jsonimg {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}// Next.js: Static generation
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60 // Regenerate every 60 seconds
};
}@react-best-practices@frontend-dev-guidelines@systematic-debugging@senior-architect