这是一篇来自 cloudflare 的 博文 ,是一篇非常好的 HTTP/2 服务器端推送的科普文。我将它翻译在此。
关于服务器端推送,有一张非常形象的图片,对,就是下面这张
对 SPDY 的增量改进
HTTP/2 的主要优点是多路复用,它允许多个 HTTP 请求共享单个 TCP 连接。与 HTTP/1.1 相比,这对性能产生了巨大影响,但这并不是什么新鲜事 - 至少从2012 年开始,SPDY 已经多路复用了 TCP 连接
2016 年左右,甚至是 2017 年,主要的 Web 服务器或 edge
网络还尚未实现 HTTP/2 的一些最重要的功能。HTTP/2 真正的亮点是 「 头部信息压缩 」 和 「 服务器端推送 」等全新的功能。
从 2016 年 2 月份以来,我们一直在悄悄地测试和部署 HTTP/2 头部信息压缩,使得那些所有使用 HTTP/2 的客户端的头部信息大小平均减少了 30%。这开启来棒极了,然而,Web 性能实现巨大飞跃的真正机会来自服务器端推送
如果谨慎使用,服务器推送可以显着提高性能。在最基本的形式中,服务器推送允许服务器 「 捆绑 」客户端不要求的资源。
它的工作原理是服务器先发送 PUSH_PROMISE
- 发送资源的意图声明,然后是实际资源内容。
在收到 PUSH_PROMISE
后,客户端可以用 RST_STREAM
消息进行响应,指示不需要该资源。但是,由于 HTTP /2 的异步特性,即使这么做了,客户端也可能会在服务器接收到 RST_STREAM
消息之前获得该资源文件。
PUSH_PROMISE
看起来很像 HTTP/2 GET 请求,客户端会在发送传出请求之前尝试匹配收到的推送 Promise 。
开启服务器端推送
我们所有使用 HTTP/2 的客户现在都启用了服务器推送,但不幸的是,服务器推送不是那些能自动正常工作的功能之一,我们需要要做一些配置工作才能真正利用服务器推送的优势。
现在,一般的实现方案是遵循 W3C 关于在 Link
头部字段中使用 preload
关键字的标准草案中规定的准则。因此,如果要为给定请求推送资源,只需在响应中添加特殊格式的 Link
头部字段。
Link: </asset/to/push.js>; rel=preload; as=script
这些 Link
头部字段可以手动添加,而且也已经存在了许多发布工具可以自动创建,像当前最流行的内容管理系统 ( CMS ),也有相应的插件可用。
当前情况下,服务器一般只推送相对链接,这意味着服务器推送不能与第三方资源一起使用。
禁用服务器推送
Link
头部字段的最初作用是在让浏览器知道它们应该预加载某些资源文件,如果由于遗留原因仍然需要此行为,则可以将 nopush
指令附加到 Link
头部信息中,就像下面一样
Link: </dont/want/to/push/this.css>; rel=preload; as=style; nopush
服务器端推送适合我吗 ?
服务器端推送看起来极具魅力不是 ? 因为它有着巨大的性能提升潜力。但是,它无法加快每个网站的速度,如果你过度热心,它甚至可能会降低性能。
一般来说,如果推送的资源从未被使用过,那么下载这些资源只会浪费带宽。在移动网络中,或者早期的家庭网络中,下行速度和上行速度都很明显的缓慢,有损。
我们建议你对你的个人网站 / API 做一些测试,测试使用和不使用服务器推送带来的性能提升。在我们自己的测试中,在移动网络上使用服务器推送时,带来了大约 45% 的性能提升
有一点需要注意的是:由于服务器端推送只在给定的 HTTP/2 TCP 连接上运行,因此它只能用于从当前域中推送资源。如果你的网站严重依赖第三方,且存在瓶颈,则服务器推送不太可能对您有所帮助
HTTP/2 服务器推送的一些最佳使用场景是:
- 不可缓存的内容 - 在客户端不能缓存的内容是服务器推送的最大受益者,因为它们可以在连接的早期就可以被发送
- 请求页面上的所有资源 - 通过在给定页面上推送所有 CSS,JS 和图像资源,可以在一次往返中传输整个页面。仅当没有第三方资源阻止页面呈现时,此功能才有用。如果大多数资源都缓存在客户端的浏览器上,则此行为可能会造成浪费
- 极可能浏览的下一个页面 - 如果加载页面上的链接很可能是下次点击的( 例如博客中的最新帖子 ),则可以同时推送 HTML 和所有页面资源。当用户点击链接时,它几乎会立即呈现
分析服务器推送
目前已经有很多支持服务器推送的工具和浏览器。但是,为了显示该功能的性能优势,我们使用的是最新的 Google Chrome 浏览器 ( 例如最新的 68.x.x.x 版本 )
下面是一个网页示例,其中有五个图像加载,有或没有服务器推送,如时间轴中所示
纯 HTTP/2
在加载主页面以及一些处理时间之后,浏览器请求五个图像。在另一次 TCP 往返之后,这些图像被传送和加载
HTTP/2 + 服务器推送
在最新的 Chrome 中,可以看到推送的资源在 Initiator
列中都被标识为 Push/Other
启用服务器推送后,我们可以看到处理页面的同时就在传送图像,因此无需额外的 TCP 往返。一旦发现需要使用图片,Chrome 就会将其与现有的推送内容相匹配,并立即使用它们
其它浏览器
Firfox
在 Firefox 浏览器中,推送的资源并不会显示时间线,而是使用 实心灰色圆圈 标识 ( 这与「 Transferred 」 选项卡中的 「 缓存 」 指示中的非实心圆圈标识的缓存内容不同 )
纯 HTTP/2
HTTP/2 + 服务器推送
其它浏览器
其它游览器有待读者自己去发现,关键是作者手上并没有合适的其它的浏览器。