关于 web-performance-optimization
面向开发者的网站性能优化技能,按测量、定位、实施和验证的流程改善加载速度、运行表现与 Core Web Vitals。
主要功能
- 01建立性能基线
- 02分析性能瓶颈
- 03优化资源与渲染路径
- 04应用缓存和延迟加载
- 05验证优化效果
适用场景
- 01排查网站加载缓慢
- 02改善 Core Web Vitals 指标
- 03缩小 JavaScript 包体积
- 04准备性能审计
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davila7/ claude-code-templates --skill web-performance-optimization安装后在 Claude Code 中输入/web-performance-optimization确认已加载。
详细介绍
Web 性能优化
概述
帮助开发者优化网站和 Web 应用性能,以改善用户体验、SEO 排名和转化率。本技能提供系统化的方法来测量、分析和改进加载速度、运行时性能以及 Core Web Vitals 指标。
何时使用本技能
- 当网站或应用加载缓慢时使用
- 当针对 Core Web Vitals(LCP、FID、CLS)进行优化时使用
- 当减小 JavaScript 打包体积时使用
- 当改善可交互时间(TTI)时使用
- 当优化图片和资源时使用
- 当实施缓存策略时使用
- 当调试性能瓶颈时使用
- 当为性能审计做准备时使用
工作原理
第 1 步:测量当前性能
我将帮助你建立基线指标:
- 运行 Lighthouse 审计
- 测量 Core Web Vitals(LCP、FID、CLS)
- 检查打包体积
- 分析网络瀑布图
- 识别性能瓶颈
第 2 步:识别问题
分析性能问题:
- 庞大的 JavaScript 打包体积
- 未优化的图片
- 阻塞渲染的资源
- 缓慢的服务器响应时间
- 缺少缓存标头
- 布局偏移
- 阻塞主线程的长任务
第 3 步:确定优化优先级
聚焦高影响的改进:
- 关键渲染路径优化
- 代码拆分和懒加载
- 图片优化
- 缓存策略
- 第三方脚本优化
第 4 步:实施优化
应用性能改进:
- 优化资源(图片、字体、CSS、JS)
- 实施代码拆分
- 添加缓存标头
- 懒加载非关键资源
- 优化关键渲染路径
第 5 步:验证改进
衡量变更的影响:
- 重新运行 Lighthouse 审计
- 对比优化前后的指标
- 监控真实用户指标(RUM)
- 在不同设备和网络上测试
示例
示例 1:优化 Core Web Vitals
## 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
<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 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
<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%)
- **FID:** 45ms ✅ (improved by 75%)
- **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
// 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
<script src="https://analytics.com/script.js"></script>
<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%)
示例 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
const images = fs.readdirSync('./images');
images.forEach(img => {
optimizeImage(\`./images/\${img}\`, './images/optimized');
});
\`\`\`
#### 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"
loading="lazy"
>
</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 |
最佳实践
✅ 应该这样做
- 先测量 - 优化前始终建立基线指标
- 使用 Lighthouse - 定期运行审计以跟踪进展
- 优化图片 - 使用现代格式(WebP、AVIF)和响应式图片
- 代码拆分 - 将大打包拆分为更小的块
- 懒加载 - 延迟加载非关键资源
- 积极缓存 - 为静态资源配置适当的缓存标头
- 最小化主线程工作 - 保持 JavaScript 执行块在 50ms 以下
- 预加载关键资源 - 对关键资源使用
<link rel="preload"> - 使用 CDN - 从 CDN 提供静态资源以实现更快的交付
- 监控真实用户 - 跟踪真实用户的 Core Web Vitals
❌ 不要这样做
- 不要盲目优化 - 先测量,再优化
- 不要忽视移动端 - 在真实的移动设备和慢速网络上测试
- 不要阻塞渲染 - 避免阻塞渲染的 CSS 和 JavaScript
- 不要一开始就加载所有内容 - 懒加载非关键资源
- 不要忘记尺寸 - 始终指定图片宽度/高度
- 不要使用同步脚本 - 使用 async 或 defer 属性
- 不要忽视第三方脚本 - 它们常常导致性能问题
- 不要跳过压缩 - 始终压缩和最小化资源
常见陷阱
问题:针对桌面端优化但在移动端缓慢
症状: 桌面端 Lighthouse 得分良好,移动端较差 解决方案:
- 在真实的移动设备上测试
- 使用 Chrome DevTools 移动端节流
- 针对 3G/4G 网络进行优化
- 减少 JavaScript 执行时间
# Test with throttling
lighthouse https://yoursite.com --throttling.cpuSlowdownMultiplier=4
问题:庞大的 JavaScript 打包体积
症状: 可交互时间(TTI)过长,FID 较高 解决方案:
- 使用 webpack-bundle-analyzer 分析打包
- 移除未使用的依赖
- 实施代码拆分
- 懒加载非关键代码
# Analyze bundle
npx webpack-bundle-analyzer dist/stats.json
问题:图片导致布局偏移
症状: CLS 分数高,内容跳动 解决方案:
- 始终指定 width 和 height
- 使用 aspect-ratio CSS 属性
- 使用骨架屏加载器预留空间
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
问题:服务器响应时间慢
症状: TTFB(首字节时间)高 解决方案:
- 实现服务端缓存
- 对静态资源使用 CDN
- 优化数据库查询
- 考虑静态站点生成(SSG)
// Next.js: Static generation
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60 // Regenerate every 60 seconds
};
}
性能检查清单
图片
- 转换为现代格式(WebP、AVIF)
- 实现响应式图片
- 添加懒加载
- 指定尺寸(width/height)
- 压缩图片(每张 < 200KB)
- 使用 CDN 分发
JavaScript
- 打包体积 < 200KB(gzip 压缩后)
- 实现代码分割
- 懒加载非关键代码
- 移除未使用的依赖
- 压缩和精简
- 对脚本使用 async/defer
CSS
- 内联关键 CSS
- 延迟加载非关键 CSS
- 移除未使用的 CSS
- 压缩 CSS 文件
- 使用 CSS containment
缓存
- 为静态资源设置缓存头
- 实现 service worker
- 使用 CDN 缓存
- 缓存 API 响应
- 为静态资源添加版本号
Core Web Vitals
- LCP < 2.5s
- FID < 100ms
- CLS < 0.1
- TTFB < 600ms
- TTI < 3.8s
性能工具
测量工具
- Lighthouse - 全面的性能审计
- WebPageTest - 详细的瀑布图分析
- Chrome DevTools - 性能分析
- PageSpeed Insights - 真实用户指标
- Web Vitals Extension - 监控 Core Web Vitals
分析工具
- webpack-bundle-analyzer - 可视化打包组成
- source-map-explorer - 分析打包体积
- Bundlephobia - 安装前检查包体积
- ImageOptim - 图片压缩工具
监控工具
- Google Analytics - 跟踪 Core Web Vitals
- Sentry - 性能监控
- New Relic - 应用性能监控
- Datadog - 真实用户监控
相关技能
@react-best-practices- React 性能模式@frontend-dev-guidelines- 前端开发标准@systematic-debugging- 调试性能问题@senior-architect- 性能架构
更多资源
专业提示: 优先关注 Core Web Vitals(LCP、FID、CLS)- 它们对用户体验和 SEO 排名的影响最大!
评论
支持 Markdown