今天项目遇到一个问题,请求合并和请求拆解哪一个效率更高,一直我都是认为请求合并比拆解效率上来说更好,但是其实并不是这么回事。
浏览器是可以并行下载资源的,将多个资源合并成一个资源,只使用一个HTTP请求下载,不一定会比用多个HTTP请求并行下载没有合并过的多个资源速度更快。
下面的实验内容我都是参考segmentfault中的文章:
作者:艾特老干部
名称:《合并HTTP请求 vs 并行HTTP请求,到底谁更快?》
HTTP请求过程
一个HTTP请求的主要过程是:
DNS解析(T1) -> 建立TCP连接(T2) -> 发送请求(T3) -> 等待服务器返回首字节(TTFB)(T4) -> 接收数据(T5)。
如下图所示,是Chrome Devtools中显示的一个HTTP请求,显示了HTTP请求的主要阶段,注意,Queueing阶段是请求在浏览器队列中的排队时间,并不计入HTTP请求时间。
从这个过程中,可以看出如果合并N个HTTP请求为1个,可以节省(N-1)* (T1+T2+T3+T4) 的时间。
但实际场景并没有这么理想,上面的分析存在几个漏洞:
浏览器会缓存DNS信息,因此不是每次请求都需要DNS解析。
HTTP 1.1 keep-alive的特性,使HTTP请求可以复用已有TCP连接,所以并不是每个HTTP请求都需要建立新的TCP连接。
浏览器可以并行发送多个HTTP请求,同样可能影响到资源的下载时间,而上面的分析显然只是基于同一时刻只有1个HTTP请求的场景。
实验论证
我们来做4组实验,对比一个HTTP请求加载合并后的资源所需时间,和多个HTTP请求并行加载拆分的资源所需时间。每组实验所用资源的体积大小有显著差异。
实验环境:
服务器:阿里云ECS 1核 2GB内存 带宽1M
Web服务器:Nginx (未启用Gzip)
Chrome v66 隐身模式,禁用缓存
Client 网络:wifi 带宽20M
实验代码地址:https://github.com/xuchaobei/…
实验 1
测试文件:large1.css、large2.css … large6.css,每个文件141K;large-6in1.css,由前面6个css文件合并而成,大小为846K。parallel-large.html引用large1.css、large2.css … large6.css, combined-large.html引用large-6in1.css,代码如下:
// parallel-large.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Parallel Large</title>
<link rel="stylesheet" type="text/css" media="screen" href="large1.css" />
<link rel="stylesheet