HTTP/1.1 使用「短连接」或「持久连接」,但每个 TCP 连接在同一时刻只能处理一个请求(HOL Blocking)。浏览器通常通过开启多个 TCP 连接(6-8个)缓解阻塞,但增加了服务器压力。
// HTTP/1.1 下需合并资源减少请求数(但可能影响缓存)
// 使用工具如 Webpack 合并 JS:
module.exports = {
entry: './src/index.js',
output: { filename: 'bundle.js' } // 所有模块打包成一个文件
};
HTTP/2 通过 二进制分帧层 实现多路复用,单个连接可并行处理数百个请求,彻底解决队头阻塞。资源无需合并,提升缓存利用率。
// HTTP/2 下拆分模块更优(利用细粒度缓存)
// Webpack 配置拆包:
module.exports = {
optimization: {
splitChunks: { chunks: 'all' } // 自动拆分公共依赖
}
};
建议:迁移到 HTTP/2 后,停止使用雪碧图、合并 CSS/JS,改为独立文件 + 长期缓存(hash 文件名)。
HTTP/1.1 的头部以纯文本传输,重复头部(如 Cookie、User-Agent)造成冗余。
HTTP/2 使用 HPACK 算法,通过静态表(61个常用头)、动态表和 Huffman 编码压缩头部,减少 30%~90% 的开销。
# Nginx 配置(默认启用 HPACK)
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
注意:避免滥用 Cookie,控制 Header 大小(如用 JWT 替代 Session Cookie)。
HTTP/2 允许服务器主动推送资源,减少 RTT(Round-Trip Time)。适用于关键路径资源(如 CSS、字体)。
# Nginx 推送示例:当请求 index.html 时推送 style.css
location = /index.html {
http2_push /static/style.css;
}
// Node.js 实现推送(使用 http2 模块)
const http2 = require('http2');
const server = http2.createSecureServer({ cert, key });
server.on('stream', (stream, headers) => {
if (headers[':path'] === '/index.html') {
stream.pushStream({ ':path': '/style.css' }, (pushStream) => {
pushStream.respondWithFile('/static/style.css');
});
stream.respondWithFile('/index.html');
}
});
建议:
preload
头部替代 Push(更灵活)html
HTTP/2 允许为每个流设置权重(1~256)和依赖关系,优化关键资源加载顺序。
javascript
// 前端通过 Importance 属性提示优先级
fetch('video.mp4', { importance: 'high' }); // 高优先级
fetch('analytics.js', { importance: 'low' });
注意:后端需正确配置优先级策略。例如,Nginx 默认根据资源类型分配优先级(CSS > 图片)。
Coverage
工具统计未使用代码,避免推送无用资源。[contenthash]
)。chrome://net-internals/#http2
检查推送是否生效。h2load
或 wrk
对比性能提升。# 示例:使用 h2load 压测
h2load -n 100000 -c 100 -m 100 https://yoursite.com
HTTP/2 通过多路复用、头部压缩等特性大幅提升性能,但需调整传统优化策略(如放弃合并文件)。
合理使用 Server Push 和流优先级,结合 Preload/Prefetch 精细控制资源加载,同时注意避免过度推送和头部膨胀。实践中需综合监控、压测和渐进式迁移,才能最大化协议优势。