在过去一年左右,性能优势的开发人员的景观发生了重大变化,http / 2的出现也许是最重要的。不再是http / 2的一个功能我们松了。已经到了,随之而来的是服务器推送!
除了解决常见的http / 1性能问题(例如,线路阻塞和未压缩头部的头)外,http / 2还给我们服务器推送!服务器推送允许您在网站资源甚至要求之前发送站点资源。实现http / 1优化实践(如内联)的性能优势是一种优雅的方式,但没有这种做法的缺点。
在本文中,您将了解有关服务器推送的所有信息,从它的工作原理到解决的问题。您还将学习如何使用它,如何判断它是否正常工作以及它对性能的影响。让我们开始!
什么是服务器推送?访问网站一直遵循请求和响应模式。用户向远程服务器发送请求,并且一些延迟,服务器响应请求的内容。
对web服务器的初始请求通常用于html文档。在这种情况下,服务器应答请求的html资源。然后,html被浏览器解析,其中发现了对其他资产的引用,例如样式表,脚本和图像。发现后,浏览器会为这些资产分别提出请求,然后对其进行实物回应。
典型的web服务器通信(大预览)这一机制的问题是,它迫使用户等待浏览器来查找和检索关键资产,直到经过 html文档已被下载。这会延迟渲染并增加加载时间。
通过服务器推送,我们可以解决这个问题。服务器推送让服务器抢先将网站资产“推送”到客户端,而用户没有明确要求他们。小心使用时,我们可以发送我们知道用户需要的页面。
假设您有一个网站,其中所有页面都依赖于在外部样式表中定义的样式styles.css。当用户index.html从服务器请求时,我们可以styles.css在我们开始发送响应之后推送给用户index.html。
web服务器与http / 2服务器通讯。(大预览)而不是等待服务器发送index.html和然后等待浏览器请求和接收styles.css,用户只需等待服务器与响应都 index.html和styles.css初始请求。这意味着浏览器可以开始渲染页面,而不必等待。
可以想像,这可以减少页面的渲染时间。它还解决了一些其他问题,特别是在前端开发工作流程中。
服务器推送解决什么问题?链接减少重要内容到服务器的往返是服务器推送解决的问题之一,但并不是唯一的问题。服务器推送作为许多http / 1特定优化反模式的合适替代方法,例如将css和javascript直接内置到html中,以及使用数据uri方案将二进制数据嵌入到css和html中。
这些技术发现在http / 1优化工作流程中进行购买,因为它们减少了一个页面的“感知呈现时间”,这意味着当页面的整体加载时间可能不会减少时,该页面似乎加载速度更快用户。毕竟这是有道理的。如果将css内嵌到<style>标签中的html文档中,浏览器可以开始将样式应用于html,而无需等待从外部来源获取它们。这个概念适用于使用数据uri方案的内联脚本和内联二进制数据。
带内置内容的web服务器通信(大预览)似乎是一个很好的方法来解决问题,对吧?当然 – 对于http / 1工作流程,您无需其他选择。然而,当我们这样做时,我们吞下的毒丸是内联内容无法高效缓存。当像样式表或javascript文件的资源保持外部和模块化时,可以高效地缓存。当用户导航到需要该资产的后续页面时,可以从缓存中提取该页面,从而无需对服务器进行其他请求。
网站制作
最佳缓存行为。(大预览)然而,当我们内嵌内容时,该内容没有自己的缓存上下文。它的缓存上下文与其内联资源相同。例如,以内联css为例。如果html文档的缓存策略始终从服务器获取标记的新副本,则内联css将不会自动缓存。当然,它的一部分的文档可能被缓存,但包含这个重复的css的后续页面将被重复下载。即使缓存策略较为宽松,html文档的保质期也会有限。这是我们愿意在http / 1优化工作流程中进行的权衡。它的工作,对于首次访客来说是非常有效的。第一印象通常是最重要的。
这些是服务器推送地址的问题。当您推送资产时,您将获得内联实现的实际利益,但您也可以将资产保留在保留自己的缓存策略的外部文件中。这一点有一个值得注意的地方,但是这篇文章已经结束了。现在,让我们继续吧。
我已经谈到了为什么你应该考虑使用服务器推送,以及为用户和开发人员修复的问题。现在,让我们来谈谈如何它的使用。
如何使用服务器推送使用服务器推送通常涉及使用linkhttp头,采用以下格式:
link: </css/styles.css>; rel=preload; as=style
请注意,我通常说。你上面看到的是实际的preload资源提示。这是来自服务器推送的独立和不同的优化,但是大多数(并非所有)http / 2实现将推link送包含preload资源提示的标头中指定的资产。如果服务器或客户端选择不接受推送的资源,客户端仍然可以为所指示的资源启动早期提取。
as=style标题的部分不是可选的。它通知浏览器推送资产的内容类型。在这种情况下,我们使用一个值style来表示推送的资产是样式表。您可以指定其他内容类型。请注意,省略该as值可能导致浏览器下载推送的资源两次。所以别忘了!
现在您知道如何触发推送事件,我们如何设置link标题?你可以通过两条路线:
您的web服务器配置(例如apache httpd.conf或.htaccess);后端语言功能(例如,php的header功能)。设置link您的服务器配置的标题以下是一个示例:在请求html文件时,配置apache(via httpd.conf或.htaccess)来推送样式表:
<filesmatch \.html$>
header set link </css/styles.css>; rel=preload; as=style
<filesmatch>
在这里,我们使用该filesmatch指令来匹配结尾的文件的请求.html。当符合此条件的请求时,我们向link响应中添加一个标头,该响应告诉服务器将资源推送到/css/styles.css。
旁注: apache的http / 2模块还可以使用该h2pushresource指令启动资源的推送。该指令的文档指出,如果使用link头文件方法,此方法可以提前启动。根据您的具体设置,您可能无法访问此功能。本文后面显示的性能测试使用link头文件方法。
到目前为止,nginx不支持http / 2服务器推送,到目前为止,软件的更新日志中没有指出已经添加了对它的支持。这可能会随着nginx的http / 2实现成熟而改变。
link在后端代码设置标题设置link标题的另一种方法是通过服务器端语言。当您无法更改或覆盖web服务器的配置时,这很有用。下面是一个使用php header函数设置link头文件的例子:
header(link: </css/styles.css>; rel=preload; as=style);
如果您的应用程序驻留在共享托管环境中,那么修改服务器的配置不是一个选项,那么这种方法可能就是您需要继续的。您应该能够以任何服务器端语言设置此标题。在开始发送响应正文之前,请务必这样做,以避免潜在的运行时错误。
推出多个资产到目前为止,我们所有的例子只是说明如何推动一项资产。如果你想推多个怎么办?这样做会有意义吗?毕竟,网页由不仅仅是样式表组成。以下是推送多项资产的方法:
link: </css/styles.css>; rel=preload; as=style, </js/scripts.js>; rel=preload; as=script, </img/logo.png>; rel=preload; as=image
当您要推送多个资源时,只需用逗号分隔每个推式指令。由于资源提示是通过link标签添加的,所以这种语法是如何将其他资源提示与您的推送指令混合使用。以下是将push指令与preconnect资源提示进行混合的示例:
link: </css/styles.css>; rel=preload; as=style, <https://fonts.gstatic.com>; rel=preconnect
多个link标题也是有效的。以下是如何配置apache link为html文档的请求设置多个标题:
<filesmatch \.html$>
header add link </css/styles.css>; rel=preload; as=style
header add link </js/scripts.js>; rel=preload; as=script
<filesmatch>
这种语法比将一串逗号分隔的值串起来更方便,它的工作原理相同。唯一的缺点是它并不那么紧凑,但是便利性是通过电线发送的几个额外的字节。
现在你知道如何推动资产,让我们看看如何判断它是否正常工作。
如何判断是否服务器推送工作所以,你添加了link头来告诉服务器推一些东西。剩下的问题是,你怎么知道它是否还能工作?
这取决于浏览器。最新版本的chrome将在开发人员工具中的网络实用程序的启动器列中