原文请参考:https://developers.google.com/speed/docs/best-practices/rendering?hl=zh-CN的“Parallelize downloads across hostnames”部分。
概览
从两个不同主机名获得资源能够提高下载并行度。
详解
HTTP 1.1规范(section8.1.4)指明:浏览器应允许每个主机名(hostname)可以支持至少两个并发连接(尽管新的浏览器支持更多的并发数:列表请参考Browserscope)。如果一个HTML文档包含的资源引用(如CSS,Javascript,图片等)比主机允许的最大并发数多,浏览器则发出允许的最大并发数的请求,并将剩余的请求加入队列中。一旦有请求完成,浏览器会立即发出队列中的下一批允许的最大并发数的请求,它会一直重复这个过程直到下载完所有的资源。换句话说,如果一个页面从一个host引用了超过X数量(X为每个主机允许的最大连接数)的额外请求,那么浏览器就必须按顺序依次下载它们。每X个资源耗费1个往返时间(RTT,round-trip time),所以总的请求往返时间为N/X(N为从一个主机上获取的资源数);比如:如果一个浏览器允许每个主机名可以有4个并发连接,并且一个页面可以引用同域的100个资源,那么每4个资源会占用1个往返时间,总的下载时间为25个往返时间。
可以通过从多个主机名提供资源绕开最大并发数的限制。这种方式可以“欺骗”浏览器进行额外的并行下载工作,从而获得更快的网页下载速度。然而,使用多并发连接可能导致客户端的CPU使用率升高、给每个新TCP连接的建立引入额外的请求往返时间,同时还可能会造成空缓存客户的DNS查找。因此,当超出一定连接数后,这项技术实际上会降低性能。普遍认为,根据文件大小、带宽等多种因素考虑,主机的最大数目应该在2~5个。如果你的页面需要从一个主机名获得大量静态资源,如图片等,则应考虑利用DNS别名将它们拆分在不同主机名上,我们推荐任何一个从单一主机获取超过10个资源的页面(少于10个资源的页面使用这种技术则没有必要)使用这种技术。
要想创建额外的主机名,可以在你的DNS数据库中配置子域作为CNAME记录指向同一个A记录,然后配置网络服务器从多个不同的主机中获取资源。为了获得更好的性能,如果全部或部分资源不需要使用cookie数据(大多数情况下不适用),可以考虑将所有或者部分主机的子域做成无cookie域(cookieless domain)。一定要确保将全部资源均衡分配到不同的主机名上,针对页面引用的资源使用URL里已经CNAME的主机名。
如果通过CDN管理静态文件,那么CDN则可能支持从多个主机名获取资源。
推荐
均衡跨主机名并行资源
可以并行请求大多数的静态资源,包括图片、CSS和其他二进制对象。在多主机名下,尽量均衡请求这些对象;如果做不到的话,最好的办法是保证没有一台主机超过全部提供资源主机 平均数的50%。所以,比如有40个资源、4个主机,那么每个主机理想条件下提供10个资源,最坏的情况,没有主机出现提供超过15个资源的情况;如果你有100个资源、4个主机,那么每个主机应该提供25个资源,没有主机提供超过38个资源。另外,许多浏览器不支持并行下载Javascript文件,这种情况从多主机名上获取资源就是没有好处的,所以当平衡跨主机名资源时,应从你的分配方程中删除JS文件。
支持/不支持Javascript文件并行下载的浏览器名单,请参考Browserscope.
防止外部JS阻塞并行下载
当下载外部Javascript文件时,无论主机名的数量为多少,很多浏览器仍会阻塞全部主机名的其他类型文件的下载,为了防止JS下载阻塞其他下载(同时加快JS本身的下载速度),我们可以采用如下方法:
- 最小化同一个HTML文档引用外部Javascript文档的数量。
- 以正确的方式引用外部Javascript文档,即使其在其他资源之后下载。
总是从同一主机名获取资源。
若要提高浏览器缓存的命中率,客户端应一直从同一主机名处获取资源,以保证所有引用同一资源的所有页面都使用相同的URL。
举例
为了显示地图图片,Google Maps传递了多个小图片,我们称之为“碎片(tiles)”,每一块碎片代表大地图的一小部分。当浏览器加载完每一个碎片是,便将这些碎片处理成一个完整的地图图片。因为这个过程需要无缝展示,所以尽可能快速的并行下载这些碎片就非常重要。为了使其能够并行下载,应用程序将碎片图片分配给四个主机名:,mt0, mt1, mt2 和 mt3。所以,比如在允许每个主机名6个并发连接的Firefox 3.0+中,最多可以有24个地图碎片请求可以并行发出。下面来自于Firebug的网络面板的截屏展示了这种方法在Firefox中的影响:15个请求并发,跨主机名 mt[0-3]。
其他资源
- 更多关于使用DNS别名并行下载的细节,请参考文章 Using CNAMES to get around browser connection limits.
- 更多关于通过这种技术提高性能的分析,请参考文章Optimizing Page Load Time