mcpField
W
web-performance-optimization

web-performance-optimization

github.com/sickn33开发48.7k3.0k 次安装今天更新
代码仓库

关于 web-performance-optimization

用于网站和应用性能诊断与优化的技能,适合处理加载缓慢、交互延迟和性能审计准备。内容聚焦 Core Web Vitals、JavaScript 包体积、资源优化与缓存,并要求通过可比环境测量验证结果。

主要功能

  1. 01优化 Core Web Vitals
  2. 02减少 JavaScript 包体积
  3. 03改善主线程阻塞与交互延迟
  4. 04优化图片和静态资源
  5. 05制定缓存策略并排查瓶颈

适用场景

  1. 01诊断 LCP、INP 或 CLS 问题
  2. 02缩减大型 JavaScript 构建产物
  3. 03制定图片格式与延迟加载方案
  4. 04为性能审计准备并验证优化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill web-performance-optimization

安装后在 Claude Code 中输入/web-performance-optimization确认已加载。

附带文件references/detailed-guide.md

详细介绍

Web 性能优化

详细指南

执行此技能前,请阅读详细指南。其中保留了完整的流程和参考资料。请将其中的安全要求、前置条件和验证要求视为强制要求。对于有针对性的工作,请加载相关章节;对于端到端工作,请完整阅读指南。

何时使用此技能

  • 网站或应用加载缓慢时使用
  • 针对 Core Web Vitals(LCP、INP、CLS)进行优化时使用
  • 减小 JavaScript 包体积时使用
  • 减少主线程阻塞和交互延迟(INP)时使用
  • 优化图像和资源时使用
  • 实施缓存策略时使用
  • 调试性能瓶颈时使用
  • 准备性能审计时使用

以下示例均为假设性的教学场景,并非实测结果或保证的收益。请在可比的构建版本、设备和网络条件下进行测量,并关注实际环境中的分布;不要仅根据包的字节数推断 INP。安装前请锁定与项目兼容的工具;保留原始内容,并检查依赖项/API 的变更。

示例

示例 1:优化 Core Web Vitals
## Performance Audit Results

### Current Metrics (Before Optimization)
- **LCP (Largest Contentful Paint):** 4.2s ❌ (should be < 2.5s)
- **INP (Interaction to Next Paint):** 350ms ❌ (should be ≤ 200ms)
- **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. **INP 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

<img src="/hero.jpg" alt="Hero">


<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 INP (Interaction to Next Paint)

**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

<script src="/analytics.js"></script>


<script src="/analytics.js" defer></script>
\`\`\`

#### Fix CLS (Cumulative Layout Shift)

**Problem:** Images without dimensions cause layout shifts

**Solutions:**
\`\`\`html

<img src="/product.jpg" alt="Product">


<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%)
- **INP:** 150ms ✅ (improved by 57%)
- **CLS:** 0.05 ✅ (improved by 80%)
- **Lighthouse Score:** 94/100 ✅
示例 2:减小 JavaScript 包体积
## 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
// Tree shaking in webpack.config.js: production mode already enables
// optimization.usedExports and optimization.sideEffects.
// Do not set optimization.sideEffects to false: that turns the optimization off.
module.exports = {
  mode: 'production'
};

// In package.json: mark modules as side-effect-free, but list the files
// that must run when imported (CSS, polyfills). A blanket
// "sideEffects": false lets the bundler drop `import './styles.css'`.
{
  "sideEffects": ["*.css", "*.scss", "./src/polyfills.js"]
}
\`\`\`

#### 5. Optimize Third-Party Scripts

\`\`\`html

<script src="https://analytics.example/script.js"></script>


<script>
  window.addEventListener('load', () => {
    const script = document.createElement('script');
    script.src = 'https://analytics.example/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%)
示例 3:图像优化策略
## 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
fs.mkdirSync('./images/optimized', { recursive: true });
async function main() {
  const images = fs.readdirSync('./images', { withFileTypes: true });
  for (const entry of images) {
    if (entry.isFile() && /\.(png|jpe?g|webp)$/i.test(entry.name)) {
      await optimizeImage(path.join('./images', entry.name), './images/optimized');
    }
  }
}
main().catch(error => { console.error(error.message); process.exitCode = 1; });
\`\`\`

#### 2. Implement Responsive Images

\`\`\`html

<picture>
  
  <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"
  >
  
  
  <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"
  >
  
  
  <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"
    fetchpriority="high"
  >
</picture>
\`\`\`

#### 3. Lazy Loading

\`\`\`html

<img 
  src="/image.jpg" 
  alt="Description"
  loading="lazy"
  width="800"
  height="600"
>


<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 |

局限性

  • 仅当任务明确符合上述范围时,才使用此技能。
  • 不要将输出视为针对特定环境的验证、测试或专家审查的替代品。
  • 如果缺少必需的输入、权限、安全边界或成功标准,请暂停并请求澄清。

评论

支持 Markdown