2026年3月6日
网站性能优化 - 提升用户体验的关键
网站性能直接影响用户体验和 SEO 排名。本文介绍网站性能优化的各种方法。
性能指标
Core Web Vitals
| 指标 | 说明 | 良好标准 |
|---|---|---|
| LCP | 最大内容绘制 | < 2.5s |
| FID | 首次输入延迟 | < 100ms |
| CLS | 累积布局偏移 | < 0.1 |
其他指标
| 指标 | 说明 |
|---|---|
| FCP | 首次内容绘制 |
| TTFB | 首字节时间 |
| TTI | 可交互时间 |
| TBT | 总阻塞时间 |
测试工具
- PageSpeed Insights:https://pagespeed.web.dev/
- WebPageTest:https://www.webpagetest.org/
- Lighthouse:Chrome 开发者工具
- GTmetrix:https://gtmetrix.com/
前端优化
资源压缩
HTML 压缩
<!-- 移除注释、空格、换行 -->
<!DOCTYPE html><html><head><title>Page</title></head><body>Content</body></html>
CSS 压缩
/* 压缩前 */
.container {
width: 100%;
padding: 20px;
}
/* 压缩后 */
.container{width:100%;padding:20px;}
JavaScript 压缩
# 使用工具压缩
# UglifyJS
uglifyjs app.js -o app.min.js
# Terser
terser app.js -o app.min.js
代码分割
动态导入
// 按需加载模块
const module = await import('./heavy-module.js');
// React 懒加载
const LazyComponent = React.lazy(() => import('./LazyComponent'));
Webpack 代码分割
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
};
图片优化
格式选择
| 格式 | 适用场景 |
|---|---|
| WebP | 照片、图标(推荐) |
| AVIF | 照片(新格式) |
| PNG | 透明图片 |
| SVG | 图标、矢量图 |
| JPEG | 照片 |
图片压缩
# 使用工具压缩
# imagemin
npm install imagemin imagemin-webp
# TinyPNG
# https://tinypng.com/
# Squoosh
# https://squoosh.app/
响应式图片
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="Description" loading="lazy">
</picture>
<!-- 响应式尺寸 -->
<img
srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, 800px"
src="medium.jpg" alt="Description">
懒加载
<!-- 原生懒加载 -->
<img src="image.jpg" loading="lazy" alt="Description">
<!-- JavaScript 懒加载 -->
<img data-src="image.jpg" class="lazy" alt="Description">
// Intersection Observer
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('.lazy').forEach(img => observer.observe(img));
CSS 优化
关键 CSS 内联
<head>
<style>
/* 首屏关键 CSS */
.header { height: 60px; }
.hero { min-height: 400px; }
</style>
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">
</head>
CSS 选择器优化
/* 避免 */
* { box-sizing: border-box; }
div.container div.content p.text { color: red; }
/* 推荐 */
*, *::before, *::after { box-sizing: border-box; }
.text { color: red; }
减少重排重绘
// 批量修改 DOM
const fragment = document.createDocumentFragment();
items.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
fragment.appendChild(li);
});
list.appendChild(fragment);
// 使用 transform 代替 top/left
.element {
transform: translateX(100px);
}
JavaScript 优化
减少主线程阻塞
// 使用 Web Worker
const worker = new Worker('worker.js');
worker.postMessage({ data: heavyData });
worker.onmessage = (e) => {
console.log(e.data);
};
// 分片处理
function processLargeArray(array, chunkSize) {
for (let i = 0; i < array.length; i += chunkSize) {
setTimeout(() => {
processChunk(array.slice(i, i + chunkSize));
}, 0);
}
}
防抖和节流
// 防抖
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流
function throttle(fn, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
字体优化
字体加载策略
/* font-display */
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
font-display: swap;
}
预加载字体
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
子集化字体
# 使用 pyftsubset
pyftsubset font.ttf --output-file=font-subset.woff2 \
--subset-file=characters.txt \
--flavor=woff2
网络优化
减少请求数
合并文件
<!-- 合并 CSS -->
<link rel="stylesheet" href="bundle.css">
<!-- 合并 JS -->
<script src="bundle.js"></script>
内联小资源
<!-- 内联小 SVG -->
<svg>...</svg>
<!-- 内联小 CSS -->
<style>.btn{color:red}</style>
缓存策略
强缓存
# Nginx 配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
协商缓存
location ~* \.(html)$ {
etag on;
add_header Cache-Control "no-cache";
}
CDN 加速
CDN 配置
<!-- 静态资源使用 CDN -->
<link rel="stylesheet" href="https://cdn.example.com/css/style.css">
<script src="https://cdn.example.com/js/app.js"></script>
第三方库 CDN
<!-- unpkg -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
预加载预连接
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<!-- 预连接 -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- 预加载 -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="font.woff2" as="font" crossorigin>
<!-- 预获取 -->
<link rel="prefetch" href="next-page.html">
<!-- 预渲染 -->
<link rel="prerender" href="next-page.html">
服务器优化
HTTP/2 和 HTTP/3
# Nginx 开启 HTTP/2
listen 443 ssl http2;
# 开启 HTTP/3 (QUIC)
listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';
Gzip/Brotli 压缩
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml;
# Brotli 压缩(需要模块)
brotli on;
brotli_types text/plain text/css application/json application/javascript;
服务器缓存
Nginx FastCGI 缓存
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=php:100m inactive=60m;
location ~ \.php$ {
fastcgi_cache php;
fastcgi_cache_valid 200 10m;
add_header X-Cache-Status $upstream_cache_status;
}
Nginx 代理缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;
location / {
proxy_cache my_cache;
proxy_cache_valid 200 1h;
}
数据库优化
查询优化
-- 使用索引
CREATE INDEX idx_user_email ON users(email);
-- 避免 SELECT *
SELECT id, name FROM users WHERE status = 1;
-- 使用 EXPLAIN 分析
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';
连接池配置
# MySQL 连接池
max_connections: 100
wait_timeout: 28800
interactive_timeout: 28800
监控与分析
性能监控
// Performance API
const timing = performance.timing;
const metrics = {
dns: timing.domainLookupEnd - timing.domainLookupStart,
tcp: timing.connectEnd - timing.connectStart,
ttfb: timing.responseStart - timing.requestStart,
download: timing.responseEnd - timing.responseStart,
domReady: timing.domContentLoadedEventEnd - timing.navigationStart,
load: timing.loadEventEnd - timing.navigationStart,
};
// Web Vitals
import { getCLS, getFID, getLCP } from 'web-vitals';
getCLS(console.log);
getFID(console.log);
getLCP(console.log);
错误监控
// 错误捕获
window.onerror = function(msg, url, line, col, error) {
console.log({ msg, url, line, col, error });
};
// Promise 错误
window.addEventListener('unhandledrejection', function(event) {
console.log(event.reason);
});
优化清单
前端
- 压缩 HTML/CSS/JS
- 图片优化和懒加载
- 代码分割
- 关键 CSS 内联
- 字体优化
- 减少重排重绘
网络
- 启用 HTTP/2
- 启用 Gzip/Brotli
- 配置缓存策略
- 使用 CDN
- 预加载关键资源
服务器
- 优化服务器配置
- 启用服务器缓存
- 数据库优化
- 负载均衡
总结
网站性能优化是一个持续的过程:
- 测量:使用工具分析性能
- 优化:针对瓶颈进行优化
- 监控:持续监控性能指标
- 迭代:不断改进优化
性能优化能显著提升用户体验和 SEO 排名,值得投入精力。