为什么Web性能很重要?
网站性能直接影响用户体验、转化率和搜索排名。Google的研究表明,页面加载时间每增加1秒,转化率下降7%。Core Web Vitals已经成为Google搜索排名的正式因素,性能优化不再只是技术问题,而是商业问题。
用户期望网站在3秒内加载完成。超过3秒,53%的移动用户会离开。
Core Web Vitals 详解
Core Web Vitals是Google定义的三项核心指标,衡量真实用户的网页体验质量。
LCP — 最大内容绘制
LCP衡量视口中最大内容元素的渲染时间,反映页面的主要内容何时加载完成。
| 等级 | 时间 | 说明 |
|---|---|---|
| 良好 | ≤ 2.5秒 | 用户能快速看到主要内容 |
| 需改进 | 2.5 - 4秒 | 体验一般,有优化空间 |
| 差 | > 4秒 | 严重影响用户体验 |
常见的LCP元素包括:<img>、<video>的海报帧、通过 url() 加载的背景图、包含文本的块级元素。
INP — 交互到下次绘制
INP(Interaction to Next Paint)于2024年3月取代FID,衡量页面对所有用户交互的响应速度。
| 等级 | 时间 |
|---|---|
| 良好 | ≤ 200毫秒 |
| 需改进 | 200 - 500毫秒 |
| 差 | > 500毫秒 |
CLS — 累积布局偏移
CLS衡量页面内容在视觉上的稳定性,即元素在加载过程中是否发生意外移动。
| 等级 | 分数 |
|---|---|
| 良好 | ≤ 0.1 |
| 需改进 | 0.1 - 0.25 |
| 差 | > 0.25 |
图片优化
图片通常占据网页总字节数的50%以上,是性能优化的最大杠杆点。
现代图片格式
<!-- 使用 picture 元素提供多种格式 -->
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="描述性文本"
width="800" height="600"
loading="lazy" />
</picture>
响应式图片 srcset
<img
src="hero-800w.webp"
srcset="
hero-400w.webp 400w,
hero-800w.webp 800w,
hero-1200w.webp 1200w,
hero-1600w.webp 1600w"
sizes="
(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw"
alt="横幅图片"
width="1600" height="900"
loading="lazy"
decoding="async" />
CSS 图片优化
/* 图片容器预留空间,防止CLS */
.image-wrapper {
position: relative;
aspect-ratio: 16 / 9;
overflow: hidden;
}
.image-wrapper img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
/* 响应式图片使用 max-width */
.content img {
max-width: 100%;
height: auto;
}
懒加载(Lazy Loading)
懒加载延迟非关键资源的加载,仅在用户滚动到可视区域时才加载,显著减少初始加载时间。
<!-- 原生懒加载:loading="lazy" -->
<img src="photo.webp" loading="lazy" alt="照片"
width="400" height="300" />
<iframe src="video-player.html" loading="lazy"
title="视频播放器" width="560" height="315"></iframe>
<!-- JavaScript Intersection Observer 懒加载 -->
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.add('loaded');
observer.unobserve(img);
}
});
}, {
rootMargin: '200px' // 提前200px开始加载
});
document.querySelectorAll('img[data-src]').forEach(img => {
observer.observe(img);
});
</script>
注意:首屏关键图片不要使用懒加载,应该使用 fetchpriority="high" 优先加载。
代码分割与按需加载
// 动态导入实现代码分割
async function loadEditor() {
const { Editor } = await import('./modules/editor.js');
return new Editor('#container');
}
// 路由级别的代码分割(React示例)
const Home = React.lazy(() => import('./pages/Home'));
const About = React.lazy(() => import('./pages/About'));
// 点击时加载非关键CSS
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'print-styles.css';
link.media = 'print';
document.head.appendChild(link);
缓存策略
| 策略 | 适用场景 | Cache-Control 头 |
|---|---|---|
| 强缓存 | 带版本号的静态资源 | max-age=31536000, immutable |
| 协商缓存 | HTML文件、API响应 | no-cache |
| 不缓存 | 敏感数据 | no-store |
// Service Worker 缓存策略
self.addEventListener('fetch', (event) => {
// 缓存优先策略(适用于静态资源)
if (event.request.destination === 'image') {
event.respondWith(
caches.match(event.request).then(cached => {
return cached || fetch(event.request).then(response => {
const clone = response.clone();
caches.open('images-v1').then(cache => cache.put(event.request, clone));
return response;
});
})
);
}
});
预加载与预连接
<!-- 预连接关键域名 -->
<link rel="preconnect" href="https://cdn.example.com" />
<link rel="dns-prefetch" href="https://analytics.example.com" />
<!-- 预加载关键资源 -->
<link rel="preload" href="/fonts/main.woff2" as="font"
type="font/woff2" crossorigin />
<link rel="preload" href="/css/critical.css" as="style" />
<link rel="preload" href="/images/hero.webp" as="image"
type="image/webp" />
<!-- 预获取下一个页面 -->
<link rel="prefetch" href="/next-page.html" />
字体优化
/* 字体优化最佳实践 */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom-font.woff2') format('woff2'),
url('/fonts/custom-font.woff') format('woff');
font-display: swap; /* 先显示系统字体,加载后替换 */
font-weight: 400 700; /* 变体字体范围 */
unicode-range: U+4E00-9FFF; /* 仅加载需要的字符范围 */
}
/* 可变字体(更小的文件体积) */
@font-face {
font-family: 'VariableFont';
src: url('/fonts/variable.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: swap;
}
/* 使用系统字体栈避免字体加载 */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial,
'Noto Sans SC', 'PingFang SC', sans-serif;
}
性能测量工具
| 工具 | 类型 | 用途 |
|---|---|---|
| Lighthouse | Chrome内置 | 综合性能审计,给出评分和建议 |
| Chrome DevTools Performance | Chrome内置 | 深入分析运行时性能瓶颈 |
| PageSpeed Insights | 在线工具 | 结合实验室和真实用户数据 |
| Web Vitals JS库 | JavaScript库 | 在生产环境收集真实用户指标 |
| 1000test | 在线工具 | 多地区性能测试 |
性能优化检查清单
- 图片使用WebP/AVIF格式并设置尺寸
- 启用懒加载(
loading="lazy") - 实施代码分割和按需加载
- 配置合适的缓存策略
- 使用CDN分发静态资源
- 压缩HTML/CSS/JavaScript(Gzip或Brotli)
- 预连接关键域名
- 优化字体加载(font-display、子集化)
- 内联关键CSS,异步加载非关键CSS
- 减少第三方脚本影响
- Core Web Vitals达到"良好"标准
- 移动端性能与桌面端一致