网站仍然加载太慢。 在下载过程的最关键时刻,通道通常几乎完全处于空闲状态。 工程师Kazuho Oku提出的Fastly新技术将有助于更好地利用这一关键的前几秒钟。
您是否曾经在手机上下载过网站-并在没有文字的页面上浏览了10秒钟? 在加载一些不寻常的字体时,没有人喜欢坐在空白屏幕上看。 因此,将此类重要事物的负载转移到最早可能的时间是有意义的。 预载
链接rel = preload可以部分解决问题。 首先,浏览器解析HTTP标头,因此这是指向预加载以后肯定需要的资源的理想位置。
默认情况下,互联网速度很慢
让我们看看如果不使用预加载会发生什么。 浏览器只能在发现需要资源后才能开始加载资源。 对于文档的初始解析期间HTML中的资源(例如,
<script>
,
<link rel=stylesheet>
和
<img>
),这种情况最有可能发生。
构建渲染树后检测到的资源下载速度较慢(这是页面由于加载字体而变慢的地方,因为要理解这一点,您首先需要加载样式表,解析它,构建CSS对象模型,然后再渲染树)。
加载速度更慢的是使用由
DOMContentLoaded
类的事件触发的JavaScript加载器将资源添加到文档中。 如果将所有内容放在一起,我们会得到一个未经优化且毫无意义的瀑布。 大多数情况下,通道处于空闲状态,并且资源加载早于必要时间或太晚:

链接rel =预加载有很大帮助
在过去的几年中,由于
Link rel = preload ,情况有所改善。 例如:
Link: </resources/fonts/myfont.woff>; rel=preload; as=font; crossorigin Link: </resources/css/something.css>; rel=preload; as=style Link: </resources/js/main.js>; rel=preload; as=script
由于有了这些指令,浏览器可以在接收到标头之后以及开始分析HTML主体之前立即开始加载资源:

这是一个重大的改进,尤其是对于大页面和关键资源(否则会发现得太晚)。 特别是对于字体,但是任何东西都可以成为关键资源,例如加载JavaScript应用程序所需的数据文件。
但是,我们可以做的更多。 毕竟,浏览器在完成发送请求的那一刻到接收到响应的第一个字节之间(从初始请求开始,绿色的较大片段较高)之间什么都不做。
我们在“早期技巧”的帮助下使用“服务器思考”的时间
另一方面,服务器确实很忙。 它生成一个响应并确定它是否成功。 访问数据库后,将进行API调用,身份验证等。 服务器可能会确定404错误是正确的答案。
有时服务器的冥想时间少于网络等待时间。 有时明显更多。 但重要的是要了解它们不会重叠。 当服务器在思考时,我们没有在向客户端发送数据。
但有趣的是,甚至在生成答案之前,您就已经知道了需要下载一些样式和字体才能显示页面。 毕竟,错误页面通常使用与常规页面相同的公司标识和设计。 最好
在服务器工作之前发送这些
Link: rel=preload
。 这就是HTTP工作组在
RFC8297中构思的
Early Hints标准由我的同事Kazuho Oku快速创建的原因。
在一个答案中评估
多个状态栏的魔力:
HTTP/1.1 103 Early Hints Link: <some-font-face.woff2>; rel="preload"; as="font"; crossorigin Link: <main-styles.css>; rel="preload"; as="style" HTTP/1.1 404 Not Found Date: Fri, 26 May 2017 10:02:11 GMT Content-Length: 1234 Content-Type: text/html; charset=utf-8 Link: <some-font-face.woff2>; rel="preload"; as="font"; crossorigin Link: <main-styles.css>; rel="preload"; as="style"
服务器可以在收到请求后立即记录第一个所谓的
“信息”响应代码 ,并将其发送到网络。 然后,他将处理一个真实反应及其产生的定义。 同时,在浏览器中,您可以更早地开始预加载:

当然,这将需要对浏览器,服务器和CDN的操作进行某些更改,并且某些浏览器的开发人员对实现的困难表示了保留。 因此,尚不清楚何时可以运行这些标头。 您可以在
Chrome和
Firefox的公共跟踪器中跟踪进度。
我们希望最终,您将能够直接从Fastly发出Early Hints标头,而仍以标准方式发送请求。 我们尚未决定如何通过VCL设置界面,因此,如果您对此主题有任何希望,请告诉我!
但是HTTP / 2 Server Push呢?
使用HTTP / 2,有一种称为“服务器推送”的新技术似乎可以解决与“早期提示”答案中的Link rel = preload相同的问题。 尽管它确实有效(并且您甚至可以在Fastly中
从边缘服务器快速生成
自定义推送 ),但在以下几点上仍存在重大差异:
- 服务器不知道客户端上资源的可用性,因此通常会不必要地推送资源。 由于网络缓冲和延迟,客户端通常无法在接收所有内容之前取消发送。 (尽管可以通过建议的Cache Digest标题的形式来解决此问题,但Kazuho正在与Akamai的Joam Weiss合作。)
- 流式传输的资源与连接相关联,因此可以轻松启动客户端不使用的资源,因为它正尝试通过另一个连接获取资源。 客户端可能需要使用不同的连接,因为该资源位于具有不同TLS证书的不同来源中,或者因为该资源是以不同的凭证模式进行检索的。
- H2 Push在不同的浏览器中并不是很一致地实现 。 因此,很难预测在您的特定情况下它是否会起作用。
早期提示和服务器推送以一种或多种方式提供不同的权衡。 早期提示可以更有效地利用网络来交换其他数据包。 如果您希望网络延迟很短并且需要花费很长时间来考虑服务器,那么Early Hints是正确的解决方案。
但是,并非总是如此。 让我们乐观一点,想象人们很快就会安定在火星上。 对于每次交换软件包,他们将以20-45分钟的延迟浏览网络,因此额外的交换非常痛苦,与之相比,服务器时间可以忽略不计。 服务器推送在这里轻松获胜。 但是,如果我们看过火星的网页,就更有可能下载某种数据包,例如现在提供并
签署了交易的 Web包 。
额外奖金:更快的请求崩溃
尽管“早期提示”应该主要在浏览器中使用,但CDN有一个有趣的潜在好处。 当快速收到许多对同一资源的请求时,我们通常仅将其中一个发送到源,然后将其余请求放入等待队列。 此过程称为
请求崩溃 。 如果来自源的响应包括
Cache-Control: private
,那么您应该从队列中删除所有请求并将它们分别发送到源,因为我们不能使用一个答案来满足多个请求。
在收到对第一个请求的响应之前,我们无法做出决定,但是在支持Early Hints的情况下,如果服务器以Cache-Control标题返回了Early Hints响应,我们将更早地知道队列无法折叠为单个请求,而是立即将所有请求从队列转发到源。
使用优先提示订购不太重要的内容
早期技巧是访问队列中一些最有价值的对象的好方法(瀑布):当网络空闲时,用户等待,路上只有一个请求,而屏幕上没有任何内容。 但是,一旦加载HTML并分析了页面,则需要加载的资源数量将急剧增加。 现在重要的是不要尽快加载资源,而要以正确的顺序加载它们。
浏览器使用令人惊讶的复杂启发式数组来独立确定下载的优先级,但是如果您要重新定义它们,那么将来可以使用
优先级提示来完成:
<script src="main.js" async importance="high"></script> <script src="non-critical-1.js" async importance="low"></script>
利用这一重要的新属性,开发人员可以在网络竞争的情况下控制资源的加载顺序。 可能会延迟低优先级的资源,直到处理器和网络空闲,或者取决于设备的类型。
可以使用吗?
早期的线索和优先的线索都尚未成为标准。 最近,由Fastly使用和支持的HTTP / 2服务器H2O开始使用Early Hints(请参阅PR
1727和
1767 ),并且
打算在Chrome中实现Priority Hints ,并积极跟踪1xx响应。 同时,立即开始发送“早期提示”没有害处-如果您想领先于潮流,那就去吧!