前端性能优化:让你的网站快如闪电
用户耐心有限。页面加载超过 3 秒,53% 的用户会选择离开。
性能优化不是锦上添花,而是决定产品成败的关键因素。这篇文章从实战出发,总结了一套可落地的优化方案。
性能指标
首先明确要优化什么:
| 指标 | 全称 | 目标值 |
|------|------|--------|
| FCP | 首次内容绘制 | < 1.8s |
| LCP | 最大内容绘制 | < 2.5s |
| FID | 首次输入延迟 | < 100ms |
| CLS | 累积布局偏移 | < 0.1 |
| TTI | 可交互时间 | < 3.8s |
使用 Lighthouse 或 Web Vitals 库测量这些指标。
1. 资源优化
图片
图片通常是页面最大的资源:
html
<!-- WebP 格式 + 响应式 -->
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="描述" loading="lazy" width="800" height="600">
</picture>css
/* CSS 中的图片优化 */
.hero {
background-image: url('hero-small.webp');
}
@media (min-width: 768px) {
.hero {
background-image: url('hero-large.webp');
}
}代码压缩
javascript
// terser 配置(webpack)
{
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: { drop_console: true },
},
}),
],
},
}2. 缓存策略
浏览器缓存
nginx
# Nginx 缓存配置
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location /images/ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
location / {
expires -1;
add_header Cache-Control "no-cache";
}Service Worker
javascript
// 注册 Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// sw.js - 缓存优先策略
const CACHE_NAME = 'v1';
const urlsToCache = ['/', '/styles.css', '/app.js'];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});3. 渲染优化
代码分割
javascript
// React.lazy + Suspense
import React, { lazy, Suspense } from 'react';
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<div>加载中...</div>}>
<HeavyComponent />
</Suspense>
);
}
// webpack 动态导入
const LazyPage = () => import('./pages/Dashboard');关键 CSS 内联
html
<!DOCTYPE html>
<html>
<head>
<style>
/* 首屏关键 CSS 直接内联 */
.header { display: flex; align-items: center; }
.hero { min-height: 60vh; }
</style>
<!-- 非关键 CSS 异步加载 -->
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
</head>4. 网络优化
HTTP/2 多路复用
nginx
# Nginx 启用 HTTP/2
server {
listen 443 ssl http2;
server_name example.com;
# HTTP/2 下不需要做域名散列
# 所有资源通过同一个连接传输
}预加载关键资源
html
<!-- 预加载关键资源 -->
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="preload" href="hero.webp" as="image">
<link rel="preconnect" href="https://api.example.com">
<!-- 预获取下一页 -->
<link rel="prefetch" href="/next-page">5. JavaScript 优化
javascript
// 1. 防抖与节流
function debounce(fn, delay = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
function throttle(fn, limit = 100) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
fn(...args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
// 2. 虚拟列表
function VirtualList({ items, itemHeight, containerHeight }) {
const [scrollTop, setScrollTop] = useState(0);
const visibleCount = Math.ceil(containerHeight / itemHeight);
const startIndex = Math.floor(scrollTop / itemHeight);
return (
<div onScroll={e => setScrollTop(e.target.scrollTop)}>
<div style={{ height: items.length * itemHeight }}>
<div style={{ transform: `translateY(${startIndex * itemHeight}px)` }}>
{items.slice(startIndex, startIndex + visibleCount + 2).map(item => (
<div key={item.id} style={{ height: itemHeight }}>{item.content}</div>
))}
</div>
</div>
</div>
);
}6. 性能监控
javascript
// Web Vitals 收集
import { onLCP, onFID, onCLS } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
url: location.href
});
// 发送到分析服务
navigator.sendBeacon('/analytics', body);
}
onLCP(sendToAnalytics);
onFID(sendToAnalytics);
onCLS(sendToAnalytics);优化检查清单
font-display: swap性能优化不是一次性工作,而是一个持续迭代的过程。先用 Lighthouse 找出瓶颈,然后针对性优化,最后用数据验证效果。
推荐指数:⭐⭐⭐⭐⭐
检测工具:https://pagespeed.web.dev/
💬 评论区 (0)
暂无评论,快来抢沙发吧!