再谈ServerPush,Push or Not Push

html

互联网工程任务组(IETF)于2014年12月将HTTP/2标准提议递交至互联网工程指导组(IESG)进行讨论,于2015年2月17日被批准,于2015年5月以RFC 7540正式发表。-维基百科前端

回过头来看,距离HTTP/2标准发布已通过去了五年。这五年,前端发生了技术翻天覆地的变化: IE浏览器逐渐式微,MVVM框架的兴起和繁盛,WebAssembly的萌芽。nginx

这五年,HTTP/2 的普及和推开也无比迅速。面试

根据最新的数据,HTTP/2的浏览器支持程度已经来到了使人振奋的96%浏览器

再看HTTP/2

缓存

HTTP/2 相较于 HTTP1.x 有哪些改进?性能优化

上面这个问题已经成为前端面试的必考题。二进制分帧、多路复用、头部压缩、服务端推送这几个关键词你们已经熟的不能再熟。服务器

HTTP/2带来了显而易见的性能提高,又有着如此高的浏览器支持度,和极低的使用成本,不用简直天理难容。目前中国各大网站都使用 HTTP/2 提高网站加载性能和用户体验。markdown

但咱们再看HTTP/2的几大特性,二进制分帧、多路复用、头部压缩这几个自没必要多说,只要开启了HTTP/2,就可使用这些特性,给网站带来性能优化。那么,Server Push去哪了?cookie

咱们找遍了中国各大门户网站,都没有看到Server Push的身影。问题出在哪?

Why not Push

简单回顾一下Server Push的概念:

服务器推送(server push)指的是,尚未收到浏览器的请求,服务器就把各类资源推送给浏览器。

上面这张图片看起来很美妙,当使用Server Push时,CSS和HTML一块儿返回,从而减小了一个RTT的时间

让咱们试着解决第一个问题:

为何Server Push没有获得普遍的应用?

须要配置?

ServerPush是HTTP/2 协议里面惟一一个须要开发者本身配置的功能,其余功能都是服务器和浏览器自动实现,不须要开发者关心。

是不是由于须要配置,才使得Server Push难以推广?

Nginx和Apache等网关早已支持Server Push功能,只须要简单配置后,在HTML的Response的Header中带上:

Link: ; rel=preload; as=style
复制代码

即可以轻松实现ServerPush😁。

一两句简单的配置,没法阻挡开发者对于极致性能的追求,那么还有其余缘由吗?

CDN带来的痛

上图中Without Push和With Push对比只是最简单的场景,基本不可用于实际的生产中。

在实际的场景中,为了提高加载速度和减轻服务器的负载,通常会使用CDN进行资源的加载。因而乎,咱们的加载时序图就会变成这样:

彷佛也不复杂,只要咱们的CDN支持Server Push,同Nginx同样,带上相应的Header,即可以实现ServerPush。

继续研究一下 ServerPush CDN的支持状况:在2016年4月28日,国外最大的提供商cloudflare宣布支持ServerPush。

而反观国内,各大CDN厂商仿佛对ServerPush这一HTTP/2特性熟视无睹。腾讯云、阿里云两大云厂商CDN产品文档都没有相关说明。只有一家小厂”又拍云“在2018年出过一篇PR文章:

让互联网更快,Server Push 特性及开启方式详解

通过重重查找,咱们发现了一些端倪:

腾讯云+社区的一篇文章在开头指出,腾讯云已经支持ServerPush,而且进行了相关的性能测试。

万事俱备,只欠东风。然而,历史包袱是沉重的。静态资源和HTML不一样域让CDN ServerPush成为了梦。

以常见的一个源站与CDN不一样域的页面为例,HTML做为Web请求的入口,为了不CDN Cache致使用户没法即时更新应用,通常选择不走CDN,直接解析到Origin的Nginx上。

而JS、CSS、IMG等静态资源,则是走CDN的域名。

HTML和CSS不在同一个域下,根本没法Push

访问一下国内的各大网站,发现基本上都是用了这种静态资源与HTML不一样域的方案,要实现ServerPush,就要推进CDN主域化

CDN主域化是一个复杂、充满风险的工程,尤为是在业务高速运转时进行,无异于高速路上换轮胎。其方案要通过层层设计,本文在此就不作研究。

假设咱们已经实现了CDN主域化,Server Push是否是能够立刻提高性能呢?

未知不是武器:Push Cache

现阶段,Server没法得知Client是否有Cache

若是Client已经有该资源的Cache,那么Push的静态资源会毫无心义地浪费带宽。虽然浏览器能够经过RST_STREAM阻止Server继续向Client发送资源,可是一部分资源已经在网络中进行传输。

一些探索

Push CGI

饿了么的这篇文章:

浅谈HTTP/2 Server Push

给咱们带来的比较好的启示,文章中提到, 为了不静态资源和HTML不一样域、Push Cache这两大问题,选择了不Push静态资源,而是Push CGI请求。

相较于Preload CGI逻辑,ServerPush CGI请求可以减小1个RTT时间,而且不用考虑Cache的问题,从而稳定地带来性能上的提高。

Cache Digests(draft)

目前,IETF已经有相关草案在进行讨论,使用Cache Digests,请求带上客户端的缓存状况供服务器识别,从而解决ServerPush的Push Cache问题。

103 Early Hints(draft)

目前 103 Early Hints 信息状态响应码也一样处于草案阶段,经过简单的HTTP回包来容许用户在服务器还在准备响应数据的时候预加载一些资源。

相较于Server Push,它避免了Push Cache的问题,但性能上没有Server Push极致。

性能数据

理论性能数据

下图总结了各类方案(Preload、103 Early Hints、Server Push、Server Push + Cache Digests)的性能:

(注:不考虑HTTPS TLS握手的RTT)

能够看到,Server Push + Cache Digests在性能上拥有很大的优点。但愿它能尽快成为规范。

实测数据

Nginx Team对Server Push在实际场景下首次加载作了一次benchmark,以下所示:

原文:Introducing HTTP/2 Server Push with NGINX 1.13.9

Server Push在这种场景下也能带来必定性能提高。

When Push?

在什么状况下,咱们应该使用Server Push?

RTT过长的状况

毫无疑问,当Client与Server的过长而带宽十分充足时,ServerPush节省的一个RTT能带来很好的优化。

一个新的问题是:RTT多长时,该使用ServerPush?

Google Chrome小组的一篇文章给出了计算公式:

Rules of Thumb for HTTP/2 Push

翻译以下:

遗憾的是,咱们没法正常得知用户的带宽和RTT时间。

第一访问的用户

为了不Push Cache这一问题,咱们能够只为第一次访问的用户进行Push。

能够考虑使用Cookie来鉴别是否为第一次访问的用户,但也须要注意Cookie并不能完整的描述全部静态资源Cache的状况,举个例子:

Client Cookie没有失效,可是CSS资源的Cache已经失效,此时Server由于Client有Cookie而选择不进行Push。

固然,也能够设计更复杂的方案在Cookie中作标记,告诉Server Push的时机。

还好已经有方案来实现:

H2O 服务器提供了一个叫做 cache-aware server push的方案,原理就是将全部缓存过的资源都记录在 cookie 里,这样服务器就知道哪些资源不须要被推送了。

不过,在 cookie 里记录全部的资源路径会占用不少的空间,所以还须要将路径压缩一下。

这里能够考虑使用bloom filter来减小cookie数据量,能够点击查看这篇文章:

NGINX 支持 HTTP/2 server push 了

Client端渲染的状况

若是应用使用了SSR,Push静态资源可能会占用加载HTML的带宽,从而增长首屏时间。CSR的场景更适合Server Push。

在网络空闲时进行PUSH,只PUSH当前页面

因为Server Push可能会占据Client端本就窄小不充裕的带宽,在某些场景下,可能会起到拔苗助长的效果。

另外一个缘由是Server Push使用冷TCP链接,TCP的慢启动致使加载资源的效率比热TCP连接更慢

而下一个页面的资源由Service Worker来主动fetch相较来讲要更为合适。


参考文章

Introducing HTTP/2 Server Push with NGINX 1.13.9

Rules of Thumb for HTTP/2 Push

浅谈 HTTP/2 Server Push

让互联网更快,Server Push 特性及开启方式详解

HTTP/2之服务器推送(Server Push)最佳实践

To push, or not to push?! - The future of HTTP/2 server push - Patrick Hamann - JSConf EU 2018

相关文章
相关标签/搜索