【前端性能优化指南】2 - 加快请求速度

更多前端性能优化系列请点击这里 >>前端

在前一部分,咱们介绍了浏览器缓存。当一个请求走过了各级前端缓存后,就会须要实际发送一个请求了。git

在 HTTP 缓存中,咱们其实也有发送请求;或者是在 HTTP/2 Push 下,使用了以前链接中推送的资源。不过为了保证思路的连贯,我仍是把「发送请求」这个章节总体放在「缓存」以后了。github

介绍网络请求其实能够包含复杂的网络知识。不过,今天我们的旅程主要聚焦于“前端性能优化”。所以,主要会介绍一些在这个环节中,前端性能优化可能会作的事儿。web

1. 避免多余重定向

重定向是一个比较经常使用的技术手段。在一些状况下,你可能进行了服务迁移,修改了原有的 uri。这时候就可使用重定向,把访问原网址的用户重定向到新的 uri。还有是在一些登陆场景下,会使用到重定向技术。算法

重定向分为 301 的永久重定向和 302 的临时重定向。建议贴合语义,例如服务迁移的状况下,使用 301 重定向。对 SEO 也会更友好。chrome

同时也不要滥用重定向。曾今也见过有业务在访问后重定向 3 次的状况,其实里面有些是没必要要的。每次重定向都是有请求耗时的,建议避免过多的重定向。跨域

2. DNS 预解析

基本咱们访问远程服务的时候,不会直接使用服务的出口 IP,而是使用域名。因此请求的一个重要环节就是域名解析。浏览器

DNS 服务自己是一个树状层级结构,其解析是一个递归与迭代的过程。例如 github.com 的大体解析流程以下:缓存

  1. 先检查本地 hosts 文件中是否有映射,有则使用;
  2. 查找本地 DNS 缓存,有则返回;
  3. 根据配置在 TCP/IP 参数中设置 DNS 查询服务器,并向其进行查询,这里先称为本地 DNS;
  4. 若是该服务器没法解析域名(没有缓存),且不须要转发,则会向根服务器请求;
  5. 根服务器根据域名类型判断对应的顶级域名服务器(.com),返回给本地 DNS,而后重复该过程,直到找到该域名;
  6. 固然,若是设置了转发,本地 DNS 会将请求逐级转发,直到转发服务器返回或者也不能解析。

更详细的介绍能够看这篇文章[1]性能优化

这里咱们须要了解的是:

  • 首先,DNS 解析流程可能会很长,耗时很高,因此整个 DNS 服务,包括客户端都会有缓存机制,这个做为前端很差涉入;
  • 其次,在 DNS 解析上,前端仍是能够经过浏览器提供的其余手段来“加速”的。

DNS Prefetch[2] 就是浏览器提供给咱们的一个 API。它是 Resource Hint 的一部分。它能够告诉浏览器:过会我就可能要去 yourwebsite.com 上下载一个资源啦,帮我先解析一下域名吧。这样以后用户点击某个按钮,触发了 yourwebsite.com 域名下的远程请求时,就略去了 DNS 解析的步骤。使用方式很简单:

<link rel="dns-prefetch" href="//yourwebsite.com">
复制代码

固然,浏览器并不保证必定会去解析域名,可能会根据当前的网络、负载等情况作决定。标准里也明确写了👇

user agent SHOULD resolve as early as possible

3. 预先创建链接

咱们知道,创建链接不只须要 DNS 查询,还须要进行 TCP 协议握手,有些还会有 TLS/SSL 协议,这些都会致使链接的耗时。使用 Preconnect[3] 能够帮助你告诉浏览器:“我有一些资源会用到某个源(origin),你能够帮我预先创建链接。”

根据规范,当你使用 Preconnect 时,浏览器大体作了以下处理:

  • 首先,解析 Preconnect 的 url;
  • 其次,根据当前 link 元素中的属性进行 cors 的设置;
  • 而后,默认先将 credential 设为 true,若是 cors 为 Anonymous 而且存在跨域,则将 credential 置为 false
  • 最后,进行链接。

使用 Preconnect 只须要将 rel 属性设为 preconnect 便可:

<link rel="preconnect" href="//sample.com">
复制代码

固然,你也能够设置 CORS:

<link rel="preconnect" href="//sample.com" crossorigin>
复制代码

须要注意的是,标准并无硬性规定浏览器必定要(而是 SHOULD)完成整个链接过程,与 DNS Prefetch 相似,浏览器能够视状况完成部分工做。

4. 使用 CDN

当咱们实际把网络包发向咱们的目标地址时,确定但愿越快到达目的地越好(对应的,也会但愿越快得到响应)。而网络传输是有极限的,一样一个北京的用户,访问北京的服务器显然要比广州快不少。同时,服务的负载也会影响响应的速度。

对于静态资源,咱们能够考虑经过 CDN 来下降时延。

对于使用 CDN 的资源,DNS 解析会将 CDN 资源的域名解析到 CDN 服务的负载均衡器上,负载均衡器能够经过请求的信息获取用户对应的地理区域,从而经过负载均衡算法,在背后的诸多服务器中,综合选择一台地理位置近、负载低的机器来提供服务。例如为北京联通用户解析北京的服务器 IP。这样,用户在以后访问 CDN 资源时都是访问北京服务器,距离近,速度快。

想了解更多 CDN 的工做方式能够阅读这篇文章[4]


下图是请求声明周期中各个阶段的示意图,能够帮助咱们理解发送请求(以及接收响应)的流程。


在缓存无法知足咱们的状况下,就要开始真正发送请求了。从前端性能优化视角,咱们会关注重定向、DNS 解析等问题,从而加速请求。但这块还预留了一小部分 —— 服务端的处理与响应。

过去,咱们会将前端局限在浏览器中,可是随着 NodeJS 的兴起,不少业务都引入了基于 NodeJS 的 BFF 来为前端(客户端端)提供服务。因此我们此次的旅程也会简单聊一下,在这一阶段能够作的一些优化。


目前内容已所有更新至 ✨ fe-performance-journey ✨ 仓库中,陆续会将内容同步到掘金上。若是但愿尽快阅读相关内容,能够直接去该仓库中浏览文章。

喜欢的朋友能够 star 一下,后续也会继续更新更多性能优化相关的内容。


参考资料

  1. DNS 的解析过程
  2. Resource Hints - DNS Prefetch
  3. Resource Hints - Preconnect
  4. CDN 之我见:原理篇
  5. Understanding Resource Timing
  6. TCP 3-Way Handshake Process
  7. TCP 4 wave hands
  8. 图文还原HTTPS原理
  9. URL redirection (wikipedia)
相关文章
相关标签/搜索