目录
- 什么是RTT?[1]
- CrUX的RTT数据来自哪里?[2]
- 如何查看RTT信息?[3]
- CrUX API[4]
- Treo[5]
- Tame the Bots[6]
- 改善高延迟环境的体验[7]
- 减少传输大小[8]
- 使用CDN[9]
- 使用快速DNS提供商[10]
- 升级到HTTP/2[11]
- 关于HTTP/1.0的说明[12]
- 关键要点[13]
- 升级到TLS 1.3[14]
- TLS 1.3+0-RTT[15]
- 关键要点[16]
- 升级到HTTP/3 (QUIC)[17]
- QUIC 0-RTT[18]
- 连接迁移[19]
- 关键要点[20]
- 避免产生延迟[21]
- 避免不必要的新连接[22]
- 关键要点[23]
- 避免重定向[24]
- 关键要点[25]
- 避免预检请求[26]
- 关键要点[27]
- 提前和带外支付延迟成本[28]
preconnect
[29]- Speculation Rules API[30]
- 缓存一切[31]
- HTTP/浏览器缓存[32]
- CDN级别[33]
- 严格传输安全[34]
- 缓存你的预检请求[35]
- 关键要点[36]
- 那么,我有什么选择?[37]
- 附录[38]
上周,我在LinkedIn上发布了 一个关于CrUX新RTT数据的简短更新[39] 。去快速阅读一下 - 这些背景信息会有帮助。
Chrome最近 开始在Chrome用户体验报告(CrUX)中添加往返时间(RTT)数据[40] 。这为我们提供了关于访问者网络拓扑的有趣见解,以及我们可能受到高延迟地区影响的程度。
什么是RTT?
往返时间(RTT)基本上是延迟的一种度量 - 从一个端点到另一个端点再返回需要多长时间?如果你曾经在飞机上的wifi上对www.google.com
进行过ping
,你就测量过RTT。
延迟是网络上的一个关键限制因素:考虑到大多数网页获取的资源相对较小(相比于,比如说,下载软件更新或流媒体电影),我们发现大多数体验受延迟限制而不是带宽限制。
往返还测量了该旅程中的中间步骤,如传播延迟、传输延迟、处理延迟等。这些中间步骤超出了本文的范围,但如果你曾经运行过traceroute
,你就走对了方向。
CrUX的RTT数据来自哪里?
RTT旨在用更高分辨率的时间信息替代 有效连接类型[41] (ECT)。为此,重要的是要意识到RTT数据并不是访问者到你网站的延迟测量,而是他们延迟的一般测量。RTT不是你网站的特征,而是访问者的特征。这与说这个人来自尼日利亚或这个人使用移动设备或这个人使用高延迟连接没有什么不同。
你无法改变某人来自尼日利亚,你无法改变某人使用移动设备,你也无法改变他们的网络条件。RTT不是你的事,而是他们的事。
RTT数据应该被视为一种洞察而不是指标。如果你发现有大量用户使用高延迟连接,你需要同情地构建你的应用程序。这正是本文要讨论的内容。
如何查看RTT信息?
由于RTT数据的包含仍处于初期阶段,查看它还不像其他CrUX洞察那样简单。然而,我们有几种可用的方法 - 诚然,有些方法比其他方法更容易和免费。
CrUX API
要查看给定来源的第75百分位RTT数据,你可以使用CrUX API:
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=<KEY>" \ --header 'Content-Type: application/json' \ --data '{"origin": "https://website.com", "formFactor": "DESKTOP", "metrics": ["round_trip_time"]}'
...将<KEY>
、https://website.com
和DESKTOP
替换为相关输入。对于我的网站,我可以看到我的移动RTT为144ms,桌面RTT为89ms - 这个差异我想我们不会感到惊讶。
Treo
如果你还没有 Treo[42] 账户,你真的错过了很多。 去注册吧。[43] 这是一个神奇的工具,让性能工程师的生活变得更加轻松(也更有趣)。Treo已经开始在URL级别添加RTT数据,这非常令人兴奋:
RTT从最慢到最快排序。注意这些URL中的一些国家:这个客户有一个真正的国际受众,延迟指标对我来说非常有趣。
同样,因为RTT是一个特征而不是指标,Treo明智地将其包含在设备仪表板中,而不是,比如说,加载仪表板中。
Tame the Bots
Dave Smart[44] 在他的网站Tame the Bots上构建了 一个很棒的CrUX历史可视化工具[45] - 你可以在那里玩玩,查看来源级和URL级的CrUX数据,包括新的RTT。
一个特别好的功能是他将RTT与TTFB进行了对比 - 记住,首字节时间包括一个往返时间[46] 。
有趣的是,延迟只占我整体TTFB指标的一小部分。
改善高延迟环境的体验
在我们深入之前,我想重申这篇文章是关于优化高延迟体验的一般方法 - 它不是关于改善CrUX数据集中的指标。以下是考虑延迟的整体最佳实践建议。
本节详细介绍了我们可以进行的机会主义升级,这些升级有望改善受延迟限制的访问者的体验。
减少传输大小
简单来说...
Web服务器不会一次发送整个文件 - 它们将其分成数据包并发送这些数据包。然后在客户端重新组装。这些数据包中的每一个都有自己的RTT生命周期(尽管不一定是同步的)。这意味着需要更多数据包的较大文件将产生更多往返 - 每个往返都是延迟。文件下载的速度将是带宽和往返时间的函数。
如果你希望资源在高延迟连接上加载得更快,让它们变小仍然是一个明智的想法,尽管随着文件大小的增加,文件大小通常与可用带宽更相关。
使用CDN
减少往返时间最有效的方法之一是减少距离本身。我在布拉格有一个客户,他们的网站也托管在同一城市的本地。他们目前没有 CDN[47] ,但他们确实经历了来自全球各地的高流量水平:
在地理位置上靠近你的受众是朝着正确方向迈出的最大一步。
看看他们的受欢迎程度排名,他们在某些撒哈拉以南国家的受欢迎程度甚至超过了他们自己的祖国捷克!为这个客户设置CDN(可能是 Cloudflare[48] )是我这个项目的首要任务之一。
除了提供一整套(咳咳...)其他性能和安全功能外,使用CDN的主要好处就是地理接近性。数据传输的距离越短,到达的速度就越快。
如果你还没有使用CDN,你应该使用。如果你已经在使用,你可能已经免费获得了下面的一些或全部部分...
使用快速DNS提供商
作为一个新访客,访问你的网站的第一件事就是通过域名系统(DNS)解析IP地址。作为网站所有者,你可以在一定程度上控制使用哪家权威提供商。Cloudflare管理我的DNS,他们是 最快的之一[49] 。如果可能的话,确保你使用的是排名靠前的提供商。
升级到HTTP/2
超过75%的网络响应是通过HTTP/2发送的[50] ,这很棒!如果你属于剩下的25%,应该优先考虑升级。通过迁移到CDN,你很可能会默认获得HTTP/2支持,这样就一举两得了。
HTTP/2相比HTTP/1.1的一个关键优势是更好的连接利用率,从而减少了整体连接协商。
HTTP 1和2都运行在传输控制协议(TCP)之上。当两个HTTP端点想要通信时,它们需要通过三次握手来建立连接。这几乎都是纯粹的延迟,应该尽可能避免。
以我的网站目前144ms的移动端往返时间为例,建立一个TCP连接会是这样的:
TCP更准确地说应该是SYN和ACK的组合,但这超出了本文想要说明的范围。
在我可以发送页面的GET
请求之前,需要整整一个往返(144ms)。
HTTP/1.0存在的一个低效之处是一个连接只能满足一个请求-响应生命周期,这意味着获取多个文件(大多数网页都需要)是一个非常缓慢的过程。
为了缓解这个问题,HTTP/1.1允许同时向服务器打开多个连接。这个数量是有变化的,但通常认为是_六个_。这意味着客户端(如浏览器)可以通过打开六个连接同时下载六个文件。虽然这总体上更快,但由于打开六个单独的TCP连接,引入了六倍的累积延迟。一个补救措施是,一旦连接建立,就保持打开并重用(下一节会详细讨论)。
你可以在下面看到通过HTTP/1.1连接加载我的主页的可视化:每个DNS、TCP、TLS都可以被视为纯延迟,但我现在只讨论TCP。
注意条目1:在0.6-0.8秒左右有一些蓝色(HTML),然后在大约0.8-1.0秒有一些紫色(图像),接着在3.4-5.0秒有更多蓝色条目 - 这是连接重用的证据。
注意我们打开了5个到csswizardry.com
的连接,6个到res.cloudinary.com
的连接,总共23个TCP连接:这是大量的累积延迟!但是,注意这些连接被重用了(下一节会再次讨论)。
HTTP/2的解决方案是只打开一个TCP连接,大大减少了连接开销,并通过在该连接内多路复用流来允许多个并发下载:
HTTP/2的连接更少,重用更多。
现在我们只有两个到csswizardry.com
的连接(一个 需要启用CORS[51] ),一个到res.cloudinary.com
的连接,总共13个,全部重用。好多了!
HTTP/2通过不需要处理大量新的或额外的三次握手,减少了总体延迟。
关于HTTP/1.0的一点说明
HTTP/1.0是如此过时的协议,我在这里提到它只是作为一个趣闻。我真心希望没有人还在使用HTTP/1.0。
在HTTP/1.0中,问题因为连接在使用后立即关闭而变得更加严重。这意味着每个文件都需要自己的连接协商。每个文件都会产生一堆一次性的延迟:
有趣的是,这个网站实际上并不是运行HTTP/1.0 - 它运行的是HTTP/1.1,但通过在响应中添加Connection: close
来强制1.0行为。
每个响应都有自己的连接,并立即终止。这真的是最慢的情况了。
关键要点
升级到HTTP/2,并确保你必须打开的任何连接都被重用和持久化。
升级到TLS 1.3
希望你在上一节注意到了一些东西:连接是不安全的。我之前简单提到了DNS,我们也详细讨论了TCP,现在是时候看看TLS了。
如果你还在运行HTTP而不是HTTPS,请紧急修复这个问题。
如果我们升级到HTTP/2,我们必须同时运行HTTPS - 这是要求的一部分。因此,可以安全地假设,如果你运行的是HTTP/2,你也在安全地运行。但这确实意味着更多的延迟...
现在在我可以发送GET
请求之前需要三个往返(432ms)!额外的安全层添加在TCP连接的末尾,意味着更多的往返。我宁愿有一个安全的网站而不是一个快速的网站,但如果我真的可以选择,我会选择两者兼得。
仅仅通过升级到TLS 1.3,我们就可以获得内置的优化。TLS 1.3通过移除协议的一些遗留方面,减少了一整个往返:
现在在我可以发送GET
请求之前需要两个往返(288ms)。更快了。但还不够快。让我们继续。
TLS 1.3+0-RTT
TLS 1.3的一个额外的可选功能是用于恢复先前连接的_0-RTT_。通过在第一次握手中共享预共享密钥(PSK),我们可以同时发送GET
请求:
现在我们的GET
请求在一个往返(144ms)后就发送了!
由于安全权衡,0-RTT是TLS 1.3中的一个可选机制。
关键要点
安全性至关重要,但它不必是慢的。切换到TLS 1.3可以在新连接上减少往返次数,并在恢复的连接上实现潜在的零往返!
升级到HTTP/3 (QUIC)
通过升级到HTTP/3,我们实际上是在获得QUIC的访问权。如前所述,HTTP 1和2是建立在TCP之上的。HTTP/3是建立在QUIC之上的,QUIC在本质上更快的UDP协议之上实现了类似TCP的层。它具有TCP的所有安全性和正确性,但避免了许多延迟问题。所有这些变化和改进都从日常开发者的工作中抽象出来,你不需要改变你的工作流程,所以我不会在本文中详细说明HTTP/2和3之间,或TCP、UDP和QUIC之间的区别。
不过,我要说的是,纯粹的优雅、时间和努力投入到协议设计中,这一点在终端用户开发者那里很大程度上被忽视了,这让我心碎。我们只是在某个地方打开一个开关,所有这些东西就自动发生了。我们真的不配拥有它,但我跑题了...
也就是说,HTTP/3的一个关键改进是,因为它建立在QUIC之上,而QUIC又有访问传输层的优势,它能够将TLS作为协议的一部分提供。TLS不是在我们的初始连接之后发生,而是作为连接的一部分发生!
我们的GET
请求现在在仅仅一个往返(144ms)后就发送了!
这里有一个在DevTools中观察并行化的很好的例子:注意_Initial connection_和(标记错误的)_SSL_是并行的且相同的:
这意味着HTTP/3的最坏情况模型模仿了TLS 1.3+0-RTT的最佳情况。如果你可以访问HTTP/3,我建议你打开它。
QUIC 0-RTT
不要与TLS 1.3+0-RTT混淆,但因为TLS 1.3+0-RTT,QUIC也有自己的 0-RTT模型[52] 。这是QUIC将TLS折叠到协议本身的结果。这种新的协议级特性的累积效应意味着恢复的HTTP/3会话可以利用0-RTT模型向相关源发送后续请求:
现在,我们的请求在零往返(0ms)后就发送了。它不可能比这更快了(GET
到了吗?哈哈...)。
连接迁移
好像这一切还不够令人印象深刻,QUIC还给我们提供了_连接迁移_的访问权!坏消息是?
目前没有人实现它,但当他们实现时...
互联网用户,特别是移动用户,在他们的浏览生命周期中会经历网络条件的变化:在城市中行走时连接到新的基站;到家后加入自己的wifi网络;离开酒店时离开wifi网络。
这些变化中的每一个都会强制TCP协商全新的连接。TCP使用四元组方法来保持连接同步,其中客户端的IP地址和端口,加上服务器的IP地址和端口,用于识别连接。这四个参数中任何一个的变化都需要打开一个新的TCP连接。
QUIC专门设计了绕过这一点的方法,通过利用_连接ID_来识别开放的连接,使其对四元组中的任何变化都免疫。这再次要归功于QUIC是一个"从零开始"的协议。
这意味着,在我们的最佳情况下,HTTP/3可以在现有连接上无缝恢复,而不是由于网络变化而必须完全拆除和重建任何当前连接。它看起来是这样的:
图表故意留空 - 字面上什么都没发生。
在H/3世界中,最坏的情况是一个往返连接。这是一个相当不错的最坏情况:
如果我们仍在运行基于TCP的协议,如HTTP/1或2,我们的最佳情况将类似于TCP 1.3+0-RTT设置:
我们的最坏情况可能是HTTP/1或2通过TLS 1.2的情况:
拆除一切;重新做一遍。
关键要点
HTTP/3的底层协议QUIC能够默认将TLS折叠到其设计中,消除了需要依次执行连接和TLS的需求。它还可以为设备在互联网上移动时提供真正无缝的连接迁移。
避免产生延迟
好了!这些都是相当机会主义的升级,但如果a)你不能升级你的协议或b)你已经升级了所有可以升级的东西,会发生什么?最好的选择,永远是避免。俗话说,预防比治疗更便宜。我们如何完全避开延迟呢?
避免不必要的新连接
在HTTP/1.1世界中,避免过多的HTTP请求是明智的建议,因为请求和连接本质上是有限的。在HTTP/2世界中,我们被告知可以采取稍微更随意的方法。然而,在可能的情况下,避免_不必要的_连接仍然相当明智。
在可能的情况下,避免去第三方源获取任何关键路径上的内容。我以前说过,我还会一遍又一遍地说,直到每个人都听进去: 自托管你的静态资产[53] 。
我的这个客户在TTFB和首次内容绘制之间存在巨大差距,造成这种情况的一个重要原因是延迟导致的时间损失 - 协商新连接,其中许多是不必要的并且位于关键路径上(用表示):
仅在这个瀑布图中,就有1,874毫秒损失在了可避免的阻塞渲染的延迟上。
查看CrUX数据,他们访问者的RTT时间与全球最慢25%的RTT时间一致 - 这是一个需要优化延迟的客户。通过自托管大部分这些资源,我们可以立即收回很多失地。
关键要点
虽然连接不像以前那么可怕了,但建立新连接纯粹是延迟 - 避免这样做,特别是在关键路径上。
避免重定向
在任何可能的情况下,避免重定向。重定向也纯粹是延迟。我之前见过这样的情况,开发人员将所有的href
指向不带尾斜杠的URL,例如:
<a href=/products>View all products…</a>
...但他们网站的URL策略包含尾斜杠,例如:
https://wwww.website.com/products/
这意味着用户每次点击链接都会产生一个完整的延迟往返,以便提供3xx
类重定向,然后还会产生更多往返来访问Location
头中列出的资源:
不计算初始连接时间,我们损失了184毫秒的纯延迟 - 这浪费了你7.36%的LCP预算!
我建议查看你提供了多少3xx
类响应 - 仅今年一年,我就有多个客户在不知不觉中因重定向而损失了大量时间!
有趣的是,304
响应仍然是一种重定向:服务器将访问者重定向回他们的HTTP缓存。确保你没有 浪费地重新验证仍然新鲜的资源[54] :
这些文件在重复页面视图时被重新验证,因为它们都带有Cache-Control: public, max-age=0, must-revalidate
。数百毫秒的纯延迟。讽刺的是,由于它们都是指纹化的,这个客户本可以完全相反:Cache-Control: max-age=[2147483648](https://csswizardry.com/2023/10/what-is-the-maximum-max-age/), immutable
。这是我在这个项目中做的第一个修复之一。
从http
重定向到https
的行为是非常必要的,无论有任何时间损失都应该始终执行,但这可以通过使用HSTS来加速,我们稍后会讨论。
关键要点
虽然有时不可避免,但重定向也纯粹是延迟。确保你没有造成不必要的工作,并告诉你的营销部门停止使用URL缩短器。
避免预检请求
非简单HTTP请求会自动在前面加上纯延迟的预检请求。当实际请求满足某些CORS条件时,会发出预检请求,例如发出非标准请求头,或尝试发出DELETE
请求等。
这在访问API端点的单页应用中是一个常见的延迟来源。以这个客户为例:对他们API端点的请求带有一个非标准的Accept-Version
头。这会自动触发预检,以便服务器知道即将到来的请求并有机会拒绝它。
每个非简单HTTP请求前面都会加上带内预检请求。
上面的预检OPTIONS
请求带有以下请求头(为了整洁而格式化):
Origin: https://website.com Access-Control-Request-Method: GET Access-Control-Request-Headers: Accept-Version
服务器用包含相应响应头的204
响应预检请求(为了整洁而格式化):
Access-Control-Allow-Origin: https://website.com Access-Control-Allow-Methods: HEAD, GET, POST Access-Control-Allow-Headers: Accept-Charset, Accept-Encoding, Accept-Language, Accept-Version, Authorization, Cache-Control, Content-Type, Server-Id
这告诉浏览器https://website.com
被允许使用列出的方法类型和头部发出请求。
一旦这个过程完成 - 全是纯延迟 - 浏览器最终可以发出实际请求,该请求带有之前预检询问过的Accept-Version: 1.0
。
在可能的情况下,避免发出非简单请求,因为这样做会触发纯延迟的预检。会触发预检请求的条件 在MDN上列出[55] 。
如果你无法避免发出预检请求,请继续阅读。
关键要点
如果你正在构建SPA(你可能正在这样做( 而你可能不应该这样做[56] )),检查你的客户端API调用发生了什么。
提前和带外支付延迟成本
即使尽最大努力,我们也不得不承担一些延迟。像0-RTT这样的技术只适用于恢复,而完全不访问其他源几乎是不可能的。那么我们能否提前支付延迟成本呢?
preconnect
我们可以(谨慎地)使用preconnect
来预先打开到我们很快需要访问的重要源的连接。我之前 写过关于配置[57] ,所以我建议你去读一读。
preconnect
是一个提示,告诉浏览器它需要打开一个到提供的源的新连接,并将设置成本与发起请求分开:
<link rel=preconnect href=https://fonts.gstatic.com crossorigin>
这给我们在瀑布图中带来了这种很好的左移:
加速Google Fonts[58] 时preconnect
的影响。
一般来说,你只想对对页面重要的源(Google Fonts,是;Google Analytics,否)和在<head>
中没有早期引用的东西使用preconnect
。如果将preconnect
部署为 HTTP头[59] 或Early Hint,那就更好了!
Speculation Rules API
比preconnect
源更进一步的是使用新的Speculation Rules API中的prefetch
或prerender
实际预先获取资源本身。这种机制允许我们提前和在后台支付任何延迟惩罚,所以当用户点击进入下一个页面时,希望它已经获取并等待了。
我 最近写过这个[60] ,所以我再次建议你去看看,但要记住谨慎行事。对于preconnect
、prefetch
、preload
和prerender
这样的东西,越少越好。
缓存一切
如果你要做某事,尽量只做一次。
如果我们无法进行相关升级,而且我们根本无法避免产生延迟,那么我们最好努力缓存任何受延迟限制的交互的结果...
HTTP/浏览器缓存
最快的请求是从未发出的请求。确保你有一个可靠的缓存(和重新验证)策略。我已经 写过[61] 和 讲过[62] 很多关于HTTP缓存的内容,所以你可以从那里获得你需要的一切(甚至更多...)。
CDN级别
CDN只有在请求在那里终止时才能帮助解决延迟问题:任何传回源的东西都将保持在慢路径上。
为了充分发挥优势,确保你的CDN配置为充分利用边缘级缓存。如果你需要单独设置CDN(或共享)缓存值,而不是浏览器缓存,请使用 s-maxage
[63] 。
严格传输安全
当有人第一次通过http
访问你的网站时,他们很可能(希望)会被重定向到https
。如果你选择使用 HTTP严格传输安全[64] (HSTS),那么你可以让浏览器在他们那边缓存这个重定向,这意味着你在将来不会产生受延迟限制的3xx
类来将访问者推向你的安全URL。
HSTS通过Strict-Transport-Security
响应头部署,例如:
Strict-Transport-Security: max-age=31536000
这不仅更快,而且更安全。
要变得更快和更安全,你可以将你的网站添加到 HSTS预加载列表[65] 中。这将你的源硬编码到浏览器中,所以永远不会有第一次从http
到https
的3xx
重定向:你永远不会产生那种延迟(或暴露),甚至一次都不会。
缓存你的预检
如前所述,如果你无法移除预检请求,至少可以缓存它们。这与你通常的Cache-Control
头不同,而是通过专用的Access-Control-Max-Age
响应头实现。认真考虑它的值 - 这是一个重要的面向安全的功能。为了防止开发人员过于宽松,Firefox将我们限制在最多24小时,Chrome限制在仅2小时 - 即使你传入31,536,000秒(一年),你得到的最好也只是86,400(一天):
Access-Control-Max-Age: 86400
这些头,就像任何响应头一样,是每个URL的,所以你不能设置全源范围的策略(这是一个特性,而不是bug)。
关键要点
任何无法避免的延迟,承担一次并处理它。后续出现应该因为被缓存而变得无关紧要。
那么,我有什么选择?
你有很多选择,但请记住,我刚刚花了近5,000字来解释如何解决可能是你最不严重的问题。只有当你知道,而且非常明显,延迟是你最大的杀手时,你才应该着手处理本文中的大多数项目。
我的第一个建议是通过积极缓存任何昂贵的东西来尽可能地控制你当前的问题。
接下来,努力避免任何你可以微妙地重新设计或重构的东西 - 如果我们能控制的话,最好完全不做。
对于无法避免的事情,尝试带外解决:preconnect
源,或prerender
后续导航是真正的快速胜利。
除此之外,寻找机会升级以领先于曲线。协议级改进可以为我们吞噬很多预先存在的问题。
然而,我讨论的很多东西要么是:
- 通过使用一个体面的CDN就可以轻松实现,而且;
- 无论如何都是最佳实践。
附录
如果你有兴趣并排比较不同协议级别的差异:
查看完整尺寸 (29KB)[66]
非常感谢 Barry Pollard[67] 和 Robin Marx[68] 对本文的反馈和投入
讨论的协议规范可以在以下位置找到:
- TLS 1.3 – RFC 8446[69]
- QUIC – RFC 9000[70]
- HTTP/3 – RFC 9114[71]
作者:Harry Roberts
Harry Roberts是一名独立的网站性能工程顾问。他帮助各种规模的公司发现和修复网站速度问题。
这有帮助吗?[72] undefined
参考链接
- 什么是RTT?: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#what-is-rtt
- CrUX的RTT数据来自哪里?: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#where-does-cruxs-rtt-data-come-from
- 如何查看RTT信息?: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#how-can-i-see-rtt-information
- CrUX API: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#crux-api
- Treo: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#treo
- Tame the Bots: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#tame-the-bots
- 改善高延迟环境的体验: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#improving-experiences-for-high-latency-environments
- 减少传输大小: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#reduce-transfer-size
- 使用CDN: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#use-a-cdn
- 使用快速DNS提供商: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#use-a-fast-dns-provider
- 升级到HTTP/2: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#upgrade-to-http2
- 关于HTTP/1.0的说明: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#a-word-on-http10
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway
- 升级到TLS 1.3: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#upgrade-to-tls-13
- TLS 1.3+0-RTT: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#tls-130-rtt
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-1
- 升级到HTTP/3 (QUIC): https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#upgrade-to-http3-quic
- QUIC 0-RTT: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#quic-0-rtt
- 连接迁移: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#connection-migration
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-2
- 避免产生延迟: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#avoid-incurring-latency
- 避免不必要的新连接: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#avoid-unnecessary-new-connections
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-3
- 避免重定向: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#avoid-redirects
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-4
- 避免预检请求: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#avoid-preflight-requests
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-5
- 提前和带外支付延迟成本: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#pay-latency-costs-up-front-and-out-of-band
preconnect
: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#preconnect- Speculation Rules API: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#speculation-rules-api
- 缓存一切: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#cache-everything
- HTTP/浏览器缓存: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#httpbrowser-cache
- CDN级别: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#cdn-level
- 严格传输安全: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#strict-transport-security
- 缓存你的预检请求: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#cache-your-preflights
- 关键要点: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#key-takeaway-6
- 那么,我有什么选择?: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#so-what-are-my-options
- 附录: https://csswizardry.com/2024/09/optimising-for-high-latency-environments//#appendix
- 一个关于CrUX新RTT数据的简短更新: https://www.linkedin.com/feed/update/urn:li:activity:7240018342948835328/
- 开始在Chrome用户体验报告(CrUX)中添加往返时间(RTT)数据: https://groups.google.com/a/chromium.org/g/chrome-ux-report/c/mPbK5zD8Ym4/m/3Lz9oEUgAAAJ
- 有效连接类型: https://developer.mozilla.org/en-US/docs/Glossary/Effective_connection_type
- Treo: https://treo.sh/
- 去注册吧。: https://treo.sh/signup
- Dave Smart: https://tamethebots.com/about-dave
- 一个很棒的CrUX历史可视化工具: https://tamethebots.com/tools/cwv-history?url=https://csswizardry.com/
- 记住,首字节时间包括一个往返时间: https://csswizardry.com/2019/08/time-to-first-byte-what-it-is-and-why-it-matters/
- CDN: https://en.wikipedia.org/wiki/Content_delivery_network
- Cloudflare: https://www.cloudflare.com/en-gb/network/
- 最快的之一: https://www.dnsperf.com/
- 超过75%的网络响应是通过HTTP/2发送的: https://almanac.httparchive.org/en/2022/http#http2-adoption
- 需要启用CORS: https://csswizardry.com/2023/12/correctly-configure-preconnections/#when-to-use-crossorigin
- 0-RTT模型: https://blog.cloudflare.com/even-faster-connection-establishment-with-quic-0-rtt-resumption/
- 自托管你的静态资产: https://csswizardry.com/2019/05/self-host-your-static-assets/
- 浪费地重新验证仍然新鲜的资源: https://speakerdeck.com/csswizardry/cache-rules-everything?slide=92
- 在MDN上列出: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
- 而你可能不应该这样做: https://x.com/csswizardry/status/1831039135290921254
- 写过关于配置: https://csswizardry.com/2023/12/correctly-configure-preconnections/
- 加速Google Fonts: https://csswizardry.com/2020/05/the-fastest-google-fonts/
- HTTP头: https://andydavies.me/blog/2019/03/22/improving-perceived-performance-with-a-link-rel-equals-preconnect-http-header/
- 最近写过这个: https://csswizardry.com/2024/08/cache-grab-how-much-are-you-leaving-on-the-table/#prerender
- 写过: https://csswizardry.com/2019/03/cache-control-for-civilians/
- 讲过: https://slideslive.com/39021005/cache-rules-everything
s-maxage
: https://csswizardry.com/2019/03/cache-control-for-civilians/#s-maxage- HTTP严格传输安全: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
- HSTS预加载列表: https://hstspreload.org/
- 查看完整尺寸 (29KB): https://res.cloudinary.com/csswizardry/image/fetch/f_auto,q_auto/https://csswizardry.com/wp-content/uploads/2024/09/diagram-all.png
- Barry Pollard: https://x.com/tunetheweb
- Robin Marx: https://x.com/programmingart
- TLS 1.3 – RFC 8446: https://datatracker.ietf.org/doc/html/rfc8446
- QUIC – RFC 9000: https://datatracker.ietf.org/doc/html/rfc9000
- HTTP/3 – RFC 9114: https://datatracker.ietf.org/doc/html/rfc9114
- 这有帮助吗?: https://csswizardry.com/code-reviews/#fix-it-fast