分类
标签
API设计 BEM Core Web Vitals CSRF CSS CSS-in-JS CSS变量 Flexbox Grid HTTP HTTP-2 HTTP-3 HTTPS JavaScript Less RESTful Sass SSL-TLS Stylus WebSocket Web安全 Web性能 XSS 主题切换 全双工通信 前端 前端优化 前端安全 前端工程化 前端开发 前端架构 动画 后端开发 响应式设计 团队协作 媒体查询 子网格 实时通信 容器查询 层叠层 布局 性能优化 接口规范 架构设计 模块化 渲染性能 现代CSS 用户体验 移动优先 组件库 缓存策略 网络 网络协议 网络安全 网络请求 自定义属性 认证授权 设计令牌 设计系统 过渡 预处理器 颜色函数
1483 字
7 分钟
前端性能优化与网络请求
前端性能优化与网络请求
概述
前端性能优化是提升用户体验的关键,网络请求优化是其中最重要的一环。通过减少请求数量、压缩资源、合理缓存等手段,可以显著提升页面加载速度。
网络请求分析
1. 关键性能指标
- FP(First Paint):首次绘制时间
- FCP(First Contentful Paint):首次内容绘制
- LCP(Largest Contentful Paint):最大内容绘制
- FID(First Input Delay):首次输入延迟
- CLS(Cumulative Layout Shift):累计布局偏移
2. 网络瀑布图分析
DNS 查询 |====|
TCP 连接 |====|
TLS 握手 |====|
请求发送 |==|
等待响应 |=======|
接收数据 |============|
3. Chrome DevTools 网络面板
- 请求列表:查看所有网络请求
- 时间线:分析请求各阶段耗时
- 瀑布图:可视化请求时序
- 请求详情:查看请求头、响应头、内容
减少请求数量
1. 合并资源文件
// Webpack 配置示例
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
},
commons: {
name: 'commons',
minChunks: 2,
chunks: 'initial',
minSize: 0
}
}
}
}
};
2. 使用 CSS Sprites
.icon {
background-image: url('sprites.png');
background-repeat: no-repeat;
}
.icon-home {
width: 32px;
height: 32px;
background-position: 0 0;
}
.icon-user {
width: 32px;
height: 32px;
background-position: -32px 0;
}
3. 内联关键 CSS
<!DOCTYPE html>
<html>
<head>
<style>
/* 关键CSS内联 */
.header { display: flex; }
.logo { width: 100px; }
/* 非关键CSS异步加载 */
</style>
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
</html>
4. 使用 Data URLs
<!-- 小图片转为 Base64 -->
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PC9zdmc+">
<!-- CSS 中内联小图片 -->
.icon {
background-image: url('data:image/svg+xml;utf8,<svg>...</svg>');
}
压缩与优化
1. 资源压缩
# Nginx Gzip 配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/xml+rss
application/json image/svg+xml;
gzip_comp_level 6;
2. 图片优化
// 使用现代图片格式
// WebP:比 JPEG 小 25-35%,支持透明度
// AVIF:比 WebP 更优,但兼容性较差
// 响应式图片
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="描述">
</picture>
// 懒加载
<img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy">
3. 代码压缩
# 使用工具压缩
# JavaScript: UglifyJS, Terser
# CSS: CSSNano
# HTML: HTMLMinifier
# Webpack 配置
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin(),
new CssMinimizerPlugin(),
],
},
};
缓存策略
1. 浏览器缓存
# 强缓存
Cache-Control: max-age=31536000, public
Expires: Wed, 13 Mar 2027 14:30:00 GMT
# 协商缓存
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 12 Mar 2026 14:30:00 GMT
2. Service Worker 缓存
// service-worker.js
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png'
];
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 => {
if (response) {
return response; // 返回缓存
}
return fetch(event.request); // 网络请求
})
);
});
3. CDN 缓存
<!-- 使用 CDN 加速 -->
<script src="https://cdn.example.com/jquery@3.6.0.min.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/bootstrap@5.1.3/css/bootstrap.min.css">
<!-- 子资源完整性校验 -->
<script
src="https://cdn.example.com/jquery@3.6.0.min.js"
integrity="sha384-...">
</script>
请求优化
1. 预加载与预连接
<!-- DNS 预解析 -->
<link rel="dns-prefetch" href="https://api.example.com">
<!-- 预连接 -->
<link rel="preconnect" href="https://api.example.com" crossorigin>
<!-- 预加载关键资源 -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="critical.js" as="script">
<!-- 预获取可能需要的资源 -->
<link rel="prefetch" href="next-page.html" as="document">
2. 请求优先级
// 使用 fetch API 设置优先级
fetch('/api/data', {
priority: 'high' // high, low, auto
});
// 图片懒加载
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('img[data-src]').forEach(img => {
observer.observe(img);
});
3. 请求合并与批处理
// 批量请求示例
class BatchRequest {
constructor(delay = 100) {
this.requests = [];
this.timer = null;
this.delay = delay;
}
add(request) {
this.requests.push(request);
this.schedule();
}
schedule() {
if (this.timer) clearTimeout(this.timer);
this.timer = setTimeout(() => this.execute(), this.delay);
}
async execute() {
if (this.requests.length === 0) return;
const batch = this.requests.splice(0, 10); // 每次最多10个
const results = await Promise.all(
batch.map(req => fetch(req.url, req.options))
);
batch.forEach((req, index) => {
req.resolve(results[index]);
});
}
}
// 使用示例
const batch = new BatchRequest();
batch.add({
url: '/api/user/1',
resolve: response => console.log('User 1:', response)
});
监控与测量
1. Performance API
// 测量页面性能
const perfData = window.performance.timing;
const loadTime = perfData.loadEventEnd - perfData.navigationStart;
console.log(`页面加载时间: ${loadTime}ms`);
// 测量资源加载
const resources = performance.getEntriesByType('resource');
resources.forEach(resource => {
console.log(`${resource.name} 加载时间: ${resource.duration}ms`);
});
// 用户自定义测量
performance.mark('task-start');
// 执行任务...
performance.mark('task-end');
performance.measure('task-duration', 'task-start', 'task-end');
2. 真实用户监控 (RUM)
// 发送性能数据到分析服务
function sendPerformanceData() {
const data = {
url: window.location.href,
fcp: performance.getEntriesByName('first-contentful-paint')[0]?.startTime,
lcp: performance.getEntriesByName('largest-contentful-paint')[0]?.startTime,
fid: performance.getEntriesByName('first-input')[0]?.processingStart,
cls: performance.getEntriesByName('layout-shift')
.reduce((sum, entry) => sum + entry.value, 0),
timestamp: Date.now()
};
// 使用 navigator.sendBeacon 异步发送
navigator.sendBeacon('/api/performance', JSON.stringify(data));
}
// 页面卸载时发送数据
window.addEventListener('beforeunload', sendPerformanceData);
3. 性能预算
{
"performanceBudget": {
"metrics": {
"fcp": 1000,
"lcp": 2500,
"fid": 100,
"cls": 0.1
},
"resourceSizes": {
"total": 500000,
"javascript": 200000,
"css": 50000,
"images": 200000
},
"requests": {
"total": 15,
"thirdParty": 5
}
}
}
工具与自动化
1. 构建工具
// Vite 配置示例
export default {
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['lodash', 'dayjs']
}
}
},
// 代码分割
chunkSizeWarningLimit: 1000,
// 资源内联阈值
assetsInlineLimit: 4096
}
};
2. 自动化测试
// Lighthouse 自动化测试
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
async function runAudit(url) {
const chrome = await chromeLauncher.launch();
const options = {
logLevel: 'info',
output: 'json',
onlyCategories: ['performance'],
port: chrome.port
};
const runnerResult = await lighthouse(url, options);
const report = runnerResult.report;
await chrome.kill();
return JSON.parse(report);
}
// WebPageTest 集成
// 使用 webpagetest-api 包进行自动化测试
3. 持续监控
# GitHub Actions 工作流
name: Performance Monitoring
on:
schedule:
- cron: '0 0 * * *' # 每天运行
push:
branches: [main]
jobs:
performance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run Lighthouse
uses: foo-software/lighthouse-check-action@master
with:
urls: 'https://example.com'
outputDirectory: './reports'
- name: Upload Report
uses: actions/upload-artifact@v2
with:
name: lighthouse-report
path: ./reports
最佳实践总结
1. 核心原则
- 测量优先:没有测量就没有优化
- 渐进增强:确保基础功能快速可用
- 按需加载:只加载当前需要的资源
- 缓存为王:合理利用各级缓存
2. 优化 checklist
- 压缩所有文本资源(HTML、CSS、JS)
- 优化图片格式和尺寸
- 合并和减少 HTTP 请求
- 使用 CDN 分发静态资源
- 实现合理的缓存策略
- 启用 HTTP/2 或 HTTP/3
- 使用 Service Worker 缓存
- 监控真实用户性能数据
3. 持续改进
- 定期进行性能审计
- 设置性能预算并监控
- A/B 测试优化效果
- 关注 Core Web Vitals 指标
总结
前端性能优化是一个系统工程,需要从网络请求、资源加载、代码执行等多个维度进行优化。通过合理的缓存策略、资源压缩、请求优化和持续监控,可以显著提升用户体验和业务指标。
创建时间:2026-03-12 分类:前端网络 标签:性能优化, 网络请求, 前端开发, 性能监控
