这是本系列的终章,主要讲解有关HTTP在实践中的优化方案。采用遇到问题、分析问题、解决问题的思路进行叙述。
无特别说明均基于HTTP/1.x(简称H1)进行讨论,后面也会提到HTTP/2.0(简称H2)相关的反模式。css
《你所应该知道的HTTP》系列的其余篇章:web
握手延迟是指开始HTTP通讯以前所花费的时间,这里的影响因素是不少的。
握手延迟主要来自三方面:DNS查询、TCP三次握手和TLS四次握手。
DNS查询也叫域名解析,是域名转换到IP地址的过程,如今基本上都是使用域名进行URI的表示,所以DNS查询是必须的步骤。
HTTP是基于TCP的协议,所以TCP的三次握手也是不可避免的步骤。
TLS四次握手的优化已经在HTTPS篇讲过,故此处再也不重复。
咱们优化的目标就是要尽可能下降握手延迟,可用方案以下:ajax
形如:segmentfault
<link rel="dns-prefetch" href="//ajax.googleapis.com">
形如:api
<link rel="preconnect" href="//font.example.com" crossorigin>
重定向是须要在创建完TCP链接后,服务器才以301或302的状态码告知客户端,这时候一般须要从新创建TCP链接。
所以最好的解决方案固然是完全不要重定向。固然,非要重定向也能够考虑使用下面两个变通办法。浏览器
这是最直接的解决办法,不须要那么多的请求需求,天然就没有延迟。主要思路不外乎合并外联资源,但这要适度,由于若是合并的文件过大,反而会下降了加载速度。缓存
进阶篇中讲到H1的链接管理模型并未提供机制来同时请求多个资源。也就是说它须要发起请求、等待响应,以后才能发起下一个请求。资源将排队等待一问一答的加载,若是中间出现任何情况,都会致使剩下的工做被阻塞
咱们优化的目标就是要尽可能提升并发,减小队头阻塞的影响,可用方案以下:服务器
现代浏览器为了解决这个问题会对单个域名开启6个左右的链接,经过各个链接分别发送请求。它实现了某种程度上的并行,但每一个链接仍会受到“队头阻塞”的影响。
咱们能够利用这一机制,将资源分布在多个域名下,这样一个域名6个请求,两个域名就能有12个请求。但这里也涉及到增长了dns查询、TCP链接增长的问题,故须要达到一个最佳平衡,不可盲目。
Yahoo研究代表,一个网站使用2个主机名进行资源加载可达到最优。cookie
TCP的设计思路:对假设状况很保守,并可以公平对待同一网络的不一样流量的应用。它的成功并非由于传输速度快,而是由于它是最可靠的协议之一。
TCP的经过慢启动,探索当前链接拥塞窗口的合适大小。即先发送少许数据包,若是接收到响应且无丢包,就在下一次发送多一倍的数据包,直到发包上限。也就是说说TCP的传输速度是逐步加快的,并不能一会儿满速的。网络
拥塞窗口(congestion window)
拥塞窗口是指,在接收方确认数据包以前,发送方能够发出的TCP包的数量。
例如:若是拥塞窗口为1,则发送方发出1个数据包以后,只有接收方确认了那个包,才能发送下一个。
而页面文件数据量原本就不大,创建TCP链接每每还没到最佳速度就结束了,即便多条链接并发也不能保证它们性能最优。
咱们优化的目标就是要尽可能复用TCP链接,可用方案以下:
使用connection:keep-alive是H1仅有的提升TCP使用率的办法。
H1虽然提供了压缩请求内容(body)的机制,可是消息首部却没法压缩。特别是其中的cookie有时很大,这样就天然增长了每次重复的数据量传输,并且自定义头部的增长,这种状况愈来愈严重。
咱们优化的目标就是要尽可能减小消息首部,可用方案以下:
cookie虽然保存在本地,但每次请求都会被发送到服务器,须要尽可能减少cookie大小。须要较大的信息存储时,能够考虑使用其余客户端的缓存,好比:WebStorage、WebDatabases等。
资源传输通常都不须要cookie,故能够在这类域名上设置cookie禁用。
H1基本没有关于优先级的设计,单纯由浏览器决定,浏览器的有些解析过程还会阻塞资源的请求。
咱们优化的目标就是使用浏览器的特性手动安排优先级,可用方案以下:
升级到H2能够解决大部分上面提到的有关H1的性能问题,上面提到的“队头阻塞”和“低效的TCP利用”会被H2的多路复用解决,“臃肿的消息首部”会被首部表和首部压缩解决,“受限的优先级设置”会被请求优先级解决。
那前面提到的一些优化方案是否还须要保留呢?答案是否认的,一些优化方案不单没有效果反而会成为反模式,这里须要注意:
单个文件都是能够被缓存的,合并/内联实际上会失去缓存的特性。在H1的是时代牺牲缓存减小请求数是划算的,但H2时代全部资源均可并发,而且只有一个链接,因此缓存的优点会更大。
为了增长并发请求数,H1时代会将资源分散到多个域名下,但H2时代只有一个链接,而且均可并行请求,因此多个域名只会增长DNS解析的代价和创建链接的耗时。
H1时代一些不须要cookie的资源能够放在禁用cookie的域名下减小请求大小,但H2时代的头部是压缩处理的,因此将资源的域名都与主页面一致反而能够减小DNS解析。