[关闭]
@liuhui0803 2016-08-10T18:12:54.000000Z 字数 4833 阅读 2669

HTTP/2的应用实战:每天400gb图片

HTTP/2


负责发布本文的编辑请注意,本文已向原作者申请了版权并得到了批准,但对方有个要求,在文末的「阅读原文」链接中需要增加一个对方指定的 rel 标签,即使用下列形式:

  1. <link rel="canonical" href="https://99designs.com.au/tech-blog/blog/2016/07/14/real-world-http-2-400gb-of-images-per-day/" />

在发布本篇内容时还请注意调整。谢谢。

摘要

来自99designs工程团队的这篇博客文章分享了他们在构建全球最大规模在线设计作品商店过程中学到的经验。

正文

终于正式确定了的HTTP/2规范逐渐吸引了广大Web性能社区的注意。这一新协议意在解决古老的HTTP/1.x协议中有关网络性能的常见问题,同时保留了老协议所用的语义。

我们于今年初开始为小范围的静态资产运用了这一全新协议。通过成功构建全新基础结构建立信心,我们开始将所有静态资产过渡至HTTP/2。令人吃惊的是,平台上部分内容的性能不升反降。本文将对我们采用HTTP/2过程中遇到的性能退化问题进行深入研究。

我们的经验并非解决所有HTTP/2性能问题的万灵药,希望通过分享可以为大家带来启发。

为何选择HTTP/2?

无论怎样,一提到HTTP/2很多人冒出的第一个念头就是性能的大跃进,为什么说我们有关Web性能的理解都是错误的

实际上性能只是HTTP/2的差别之一。

与HTTP/1.x为每个资源建立新连接的做法不同,HTTP/2最多只为每个主机名建立一个连接。这个连接是一种通过二进制分帧协议(Binary framing protocol)建立的多路传输流(Multiplexed stream),由二进制分帧负责对不同资源的并发请求进行匹配。

HTTP/2的二进制分帧协议示意图
来自Ilya Grigorik演讲“HTTP/2已来,一起优化吧!”的一页幻灯片

由于不再受制于每个连接只能执行一个事务,头端阻塞(Head-of-line blocking)的情况有了大幅改善。所需创建的连接数量更少,这也意味着对延迟和TCP拥塞控制的敏感度大幅降低。通过配合使用,这些特性可显著改善性能,因为可大幅减少服务器和客户端之间来回往返通信的数量和所需时间。

页面加载时间在带宽占用和延迟两方面的对比图
https://www.igvita.com/2012/07/19/latency-the-new-web-performance-bottleneck

监控HTTP/2的性能

我们使用Calibre对最终用户的性能进行全面监控并收集各种度量指标,同时用非常醒目的Geckoboard将部分数据显示在办公室里。

性能仪表盘1性能仪表盘2
墨尔本办公室中受到Etsy启发开发的性能仪表盘

我们使用下列度量指标代表用户感知的页面加载性能和HTTP/2表现。使用这些指标是因为它们会受到页面加载生命周期内不同因素的影响。

测试并确认HTTP/2的成功实现

我们首先将图片缩略图的CDN换为CloudFlare,该服务内建支持HTTP/2。最初进行的性能评测显示CloudFlare的延迟和响应时间与我们原有的CDN不相上下。

作为一种设计作品的商店,我们的大部分页面都以图片为主,通常一个页面会包含超过50张图片。

包含很多小资源的页面反而容易受到HTTP/1.x连接延迟小幅变化的影响。对于这种延迟变化幅度很大的页面,我们的预期是能尽可能快速地完成视觉呈现工作。具体能快多少取决于连接延迟和图片数量,我们原本认为在高延迟低带宽的3G连接下依然会存在这种情况。

对于带宽要求高的页面,没指望能实现较大程度的改善。

单独为图片启用HTTP/2并不能缓解头端阻塞的情况,因此也没指望首次绘制或DOMContentLoaded指标能够有所改善。

实际情况

最终获得的结果并不是非常明了。下文将探讨在推行HTTP/2过程中遇到的一些差异和惊喜,以及未来的计划。

测试

我们通过一项功能标记启用HTTP/2 CDN后,一周时间里在启用或不启用新CDN的情况下抓取了大约100个Calibre截图。Calibre的Chrome代理程序位于美国,使用了低延迟高带宽连接。

案例研究:设计师作品集

99designs网站的设计师作品集通常是受延迟影响十分严重的页面。我们发现速度指数和彻底完成视觉呈现所需的时间有了5%的提高。

首次绘制所需时间也有相应提高,但有趣的是首次渲染使用HTTP/2时更为完整。

HTTP/1.x和HTTP/2页面加载性能并列对比
通过HTTP/2提供图片时的首次渲染更完整

案例研究:Discover作品库

我们的Discover作品库是整个平台中最极端的应用。每个页面包含总大小约10mb共80张图片,这些页面对带宽要求极高,因此延迟降低所实现的改善实在是微不足道。我们原本也没指望这方面的性能会有太大变化。

但实际发现在完整视觉呈现和速度指数方面平均性能反而有5%~10%的退化。然而总的来说页面加载时间减少了,这意味着我们已经从连接延迟的降低中获益。

HTTP/1.x和HTTP/2页面加载性能并列对比
HTTP/2首次绘制的延迟和完整视觉呈现所需的时间

高延迟测试

为了收集有关高延迟连接的数据,我们在3G网络环境下使用了WebPagetest

首次绘制依然显得更完整,但用的时间略微长了些。整体页面加载依然会提前进行。

让人没想到的是,完整视觉呈现的延迟竟然进一步增加了,设计师作品集平均增加15%,Discover作品库平均增加了25%。

长话短说

对于一个包含大量图片,对延迟要求较高的典型页面,使用高速低延迟连接的情况下完整可视呈现的平均速度提高了5%。

对于包含极多图片,对带宽要求较高的页面,使用同一条连接的情况下完整可视化呈现的平均速度降低了5%~10%。

在高延迟低速连接情况下,我们发现页面完成视觉呈现的过程产生了较大延迟。

所有测试中都发现页面整体加载时间有改善,并且首次绘制也更为完整。

事后分析

收集到的数据为我们提出了一个大问题:

在使用HTTP/2时尽管加载速度更快,但对带宽要求高的页面用了更长时间才完成视觉呈现。为什么?

猜测1:网络饱和

由于需要开放大量短暂连接,HTTP/1.x流量有着“突发(Bursty)”的本质。在一些开发工具的网络瀑布图中可以明显看到这种现象。

HTTP/1.x参差的网络瀑布
HTTP/1.x参差的网络瀑布

最初我们认为用一个更“长寿”的TCP连接加载数MB图片数据可能会彻底耗尽带宽,致使浏览器无法加载决定页面布局所需的资源,例如CSS、JS和字体。

然而在加载影响页面布局的资源时看到的网络瀑布图中并没有延续这样的情况。

猜测2:加载优先级的变化

在使用HTTP/1.x时,浏览器受到限制针对同一个“源”最多只能维持大约6个并发的开放连接。随着更多资源逐渐被发现,浏览器会将其加入先进先出(FIFO)资源下载队列。对同一个源所创建的开放连接进行这样的限制,实际上等于为资源的加载划分了优先级。

加入队列的每个资源请求都代表一个浏览器与源之间的往返“请求-响应”过程,必须首先完成这一过程才能让资源退出队列。这一行为也就是我们所说的网络瀑布。

HTTP/2的分帧协议使得浏览器能够将多个请求和响应“缝合”在一起,因此不再有队列文档优先级顺序这一概念。

HTTP/1.x和HTTP/2网络瀑布对比
Discover作品库页面在HTTP/1.x和HTTP/2环境下的网络时间线

HTTP/1.x时代将<script>放在文档末尾的这个最佳实践现在开始起到了反作用。

我们有关性能的认识真的都错了吗?

然而DOMContentLoaded的速度又推翻了这一理论。通过网络瀑布图可以确认决定页面布局的资源其处理优先级远高于图片。

实际上浏览器下载队列中的资源依然存在优先级的差异。也正是因此,先为80张图片发出请求随后才发现页面底部的<script>,这个顺序没有造成脚本加载的延迟。

资源的实际加载行为并无公开记录,没有特别指定,并且还会时常变化。就算不是所有浏览器,但大部分浏览器都会先于图片处理CSS、JavaScript和字体。

猜想3:传输流

由于取消了HTTP/1.x中并发连接的限制,浏览器可以更自由地同时加载这80张图片。服务器也会同时对这些针对图片的请求做出响应,下载完成的图片会立刻显示在浏览器中。我们可以从网络时间线中确认这一行为。

通过HTTP/2下载Discover作品库中图片时的网络瀑布图
通过HTTP/2处理Discover作品库页面中前20个图片请求时的网络时间线

图片的请求依然会按照预定顺序处理。然而较小的图片可能会更快速下载完成,因此可以更快速渲染出来。如果有较大的图片恰好处于最初的Viewport过程中,无疑需要更长时间才能加载,这会导致完整视觉呈现出现延迟。

使用HTTP/1.x时,Discover作品库页面加载过程Gif动图
使用HTTP/2时,Discover作品库页面加载过程Gif动
3G网络情况下使用HTTP/1.x和HTTP/2加载Discover作品库页面过程对比

同时这也解释了为什么在带宽严重不足的情况下完整视觉呈现用了更长时间,并存在如此大的变化。

HTTP/2的一些注意事项

我们在传输流方面遇到的这种问题实际上是HTTP/2中一个尚未被太多人关注的重大功能。

Ilya Grigorik对此有一个很棒的描述:

“使用HTTP/2的情况下,将由服务器决定浏览器获得响应数据的最佳方式。
和字节数无关,和每秒请求数也没关系,重点在于交付数据的顺序。你的HTTP/2服务器一定要进行慎重的测试。”

传统方式下会按照预定顺序请求不同资源,不过为了改善性能,浏览器可能会酌情进行一些调整。这种方法就造成了一个大问题:

这些调整中所产生的变化可能导致页面加载性能在没有事先通知的情况下突然发生变化。

HTTP/2彻底改变了资源优先级的处理方法,现在可由浏览器和服务器共同决定优先级。浏览器向服务器提出自己的优先级建议,但最终还是由服务器决定优先处理哪些内容。

这种“权力”的变化是一把双刃剑。

服务器端和客户端同时对资源的优先级进行调整会让整个过程更加不透明并更加碎片化。然而最终结论由服务器做出,实际上是将这个权力转嫁给了开发者。

结论

我们调查发现“性能的大跃进”根本不存在,一些浏览器厂商早就知道了。

对网站性能的追求是一个权衡和差异化的过程。

类似我们所调查的这种包含大量图片的网页,选择多路HTTP/2连接还是多个HTTP/1.x连接,可以用延迟和图片平均下载时间的趋近作为临界点。对于高延迟与低带宽的恰当组合,小图片使用HTTP/2可以获得更好的结果。

HTTP/2的实现还很年幼,围绕这一协议还需要做很多工作:

未来几年里,网上肯定会充斥着针对这些问题的调整、优化,以及必不可少的Bug。重要的是我们必须了解这项新技术的动机并权衡,这样才能从炒作中获得价值。

有关图片优化的一个注解

对于Discover作品库这种页面,进一步的图片优化无疑会降低HTTP/1和HTTP/2用户完整视觉呈现的速度,而HTTP/2用户能否从中获得较大收益这一点目前还不明显。我们还需要考虑为整个平台实施图片优化解决方案所造成的工作量和开销。

作为一种设计作品商店,图片质量至关重要。我们对此非常在意,因为对图片进行不当的或过度的优化也会对用户体验产生消极影响。

我们会经常对整个堆栈的复杂度、处理大量预览图的成本,以及其他用户体验改进措施的机会成本进行评估。在研究适合的响应性解决方案过程中,目前HTTP/2这种先进的缓存和低开销交付方式正好提供了一种恰当的平衡。

致谢

本文得到了Andrew KrespanisBen Schwarz的技术加工。谢谢你们。

作者Michael Mifsud阅读英文原文Real–world HTTP/2: 400gb of images per day

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注