web-performance-optimization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeb Performance Optimization
Web性能优化
Overview
概述
Implement performance optimization strategies including lazy loading, code splitting, caching, compression, and monitoring to improve Core Web Vitals and user experience.
实施包括懒加载、代码分割、缓存、压缩和监控在内的性能优化策略,以提升Core Web Vitals指标和用户体验。
When to Use
适用场景
- Slow page load times
- High Largest Contentful Paint (LCP)
- Large bundle sizes
- Frequent Cumulative Layout Shift (CLS)
- Mobile performance issues
- 页面加载速度缓慢
- Largest Contentful Paint (LCP) 指标过高
- 包体积过大
- Cumulative Layout Shift (CLS) 频繁发生
- 移动端性能问题
Code Splitting (React)
React代码分割
javascript
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}javascript
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}Webpack Bundle Optimization
Webpack包体积优化
javascript
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};javascript
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};Image Optimization
图片优化
html
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img
src="image.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw"
loading="lazy"
decoding="async"
alt="Description"
>
</picture>html
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img
src="image.jpg"
srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw, 50vw"
loading="lazy"
decoding="async"
alt="Description"
>
</picture>Service Worker Caching
Service Worker缓存
javascript
// sw.js
const CACHE_NAME = 'app-v1';
const ASSETS = ['/', '/index.html', '/main.js', '/styles.css'];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS))
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request).then(response => {
return caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, response.clone());
return response;
});
});
})
);
});javascript
// sw.js
const CACHE_NAME = 'app-v1';
const ASSETS = ['/', '/index.html', '/main.js', '/styles.css'];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS))
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request).then(response => {
return caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, response.clone());
return response;
});
});
})
);
});Core Web Vitals Monitoring
Core Web Vitals监控
javascript
// Track LCP, CLS, INP (Note: INP replaced FID as of March 2024)
// sendToAnalytics is a placeholder function that sends metrics to your analytics endpoint
// Expected signature: sendToAnalytics({ metric: string, value: number }) => void
// Example implementation:
function sendToAnalytics({ metric, value }) {
// Replace with your analytics implementation (e.g., Google Analytics, Segment)
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ metric, value, timestamp: Date.now() })
});
}
// Largest Contentful Paint (LCP)
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`LCP: ${entry.startTime}ms`);
sendToAnalytics({ metric: 'LCP', value: entry.startTime });
}
}).observe({ type: 'largest-contentful-paint', buffered: true });
// Cumulative Layout Shift (CLS)
new PerformanceObserver((list) => {
let cls = 0;
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) cls += entry.value;
}
sendToAnalytics({ metric: 'CLS', value: cls });
}).observe({ type: 'layout-shift', buffered: true });
// Interaction to Next Paint (INP) - replaces FID
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// INP measures responsiveness - duration of slowest interaction
const inp = entry.processingEnd - entry.processingStart;
console.log(`INP: ${inp}ms`);
sendToAnalytics({ metric: 'INP', value: inp });
}
}).observe({ type: 'event', buffered: true }); // 'event' captures interaction eventsjavascript
// 追踪LCP、CLS、INP(注:自2024年3月起INP取代FID)
// sendToAnalytics是将指标发送到分析端点的占位函数
// 预期签名:sendToAnalytics({ metric: string, value: number }) => void
// 示例实现:
function sendToAnalytics({ metric, value }) {
// 替换为你的分析实现(如Google Analytics、Segment)
fetch('/api/analytics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ metric, value, timestamp: Date.now() })
});
}
// Largest Contentful Paint (LCP)
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`LCP: ${entry.startTime}ms`);
sendToAnalytics({ metric: 'LCP', value: entry.startTime });
}
}).observe({ type: 'largest-contentful-paint', buffered: true });
// Cumulative Layout Shift (CLS)
new PerformanceObserver((list) => {
let cls = 0;
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) cls += entry.value;
}
sendToAnalytics({ metric: 'CLS', value: cls });
}).observe({ type: 'layout-shift', buffered: true });
// Interaction to Next Paint (INP) - 取代FID
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// INP衡量响应能力 - 最慢交互的持续时间
const inp = entry.processingEnd - entry.processingStart;
console.log(`INP: ${inp}ms`);
sendToAnalytics({ metric: 'INP', value: inp });
}
}).observe({ type: 'event', buffered: true }); // 'event'捕获交互事件Performance Targets
性能目标
| Metric | Good | Needs Improvement |
|---|---|---|
| LCP | <2.5s | 2.5-4s |
| INP | <200ms | 200-500ms |
| CLS | <0.1 | 0.1-0.25 |
| TTI | <3.8s | 3.8-7.3s |
Note: INP (Interaction to Next Paint) replaced FID (First Input Delay) as a Core Web Vital in March 2024. INP provides a more comprehensive measure of page responsiveness by capturing the full duration of interactions, not just the input delay.
| 指标 | 良好 | 需要改进 |
|---|---|---|
| LCP | <2.5秒 | 2.5-4秒 |
| INP | <200毫秒 | 200-500毫秒 |
| CLS | <0.1 | 0.1-0.25 |
| TTI | <3.8秒 | 3.8-7.3秒 |
注意: 自2024年3月起,INP(Interaction to Next Paint,下一次绘制交互)取代FID(First Input Delay,首次输入延迟)成为Core Web Vital指标之一。INP通过捕获交互的完整持续时间(而非仅输入延迟),更全面地衡量页面响应能力。
Compression (Nginx)
Nginx压缩配置
nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
gzip_comp_level 6;nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
gzip_comp_level 6;Best Practices
最佳实践
- Minimize bundle size with code splitting
- Optimize images with appropriate formats
- Implement lazy loading strategically
- Use HTTP caching headers
- Enable gzip/brotli compression
- Monitor Core Web Vitals continuously
- Implement service workers
- Defer non-critical JavaScript
- Optimize critical rendering path
- Test on real devices and networks
- 通过代码分割最小化包体积
- 使用合适格式优化图片
- 策略性地实现懒加载
- 使用HTTP缓存头
- 启用gzip/brotli压缩
- 持续监控Core Web Vitals指标
- 实现Service Worker
- 延迟加载非关键JavaScript
- 优化关键渲染路径
- 在真实设备和网络环境下测试
Optimization Checklist
优化检查清单
- Enable code splitting for routes
- Lazy load below-fold components
- Optimize and compress images
- Implement service worker caching
- Enable gzip/brotli compression
- Monitor Core Web Vitals
- Minimize render-blocking resources
- 为路由启用代码分割
- 懒加载视口下方的组件
- 优化并压缩图片
- 实现Service Worker缓存
- 启用gzip/brotli压缩
- 监控Core Web Vitals指标
- 最小化阻塞渲染的资源
Additional Configuration
额外配置
See references/compression-monitoring.md for:
- Webpack compression plugin setup
- Apache .htaccess compression config
- TTFB monitoring implementation
- Puppeteer automation for measurement
See references/typescript-advanced.md for:
- TypeScript lazyLoad utility
- TypeScript image component
- Advanced service worker with offline fallback
- TerserPlugin configuration
- Complete PerformanceMetrics interface
查看references/compression-monitoring.md获取:
- Webpack压缩插件配置
- Apache .htaccess压缩配置
- TTFB监控实现
- Puppeteer自动化测量方案
查看references/typescript-advanced.md获取:
- TypeScript懒加载工具
- TypeScript图片组件
- 带离线回退的高级Service Worker
- TerserPlugin配置
- 完整的PerformanceMetrics接口
Tools
工具
- Lighthouse / PageSpeed Insights
- WebPageTest
- Chrome DevTools Performance tab
- web-vitals npm package
- Lighthouse / PageSpeed Insights
- WebPageTest
- Chrome DevTools性能面板
- web-vitals npm包