资料来源 : 小林coding
小林官方网站 : 小林coding (xiaolincoding.com)
如何减少HTTP请求次数?
减少 HTTP 请求次数自然也就提升了 HTTP 性能,可以从这 3 个方面入手:
- 减少重定向请求次数
- 合并请求
- 延迟发送请求
减少重定向请求次数
我们先来看看什么是重定向请求?
服务器上的一个资源可能由于迁移、维护等原因从 ur1 移至 ur12 后,而客户端不知情,它还是继续请求ur1,这时服务器不能粗暴地返回错误,而是通过 302 响应码和 Location 头部,告诉客户端该资源已经迁移至 ur12 了,于是客户端需要再发送 ur2 请求以获得服务器的资源。
那么,如果重定向请求越多,那么客户端就要多次发起 HTTP 请求,每一次的 HTTP 请求都得经过网络这无疑会越降低网络性能。
另外,服务端这一方往往不只有一台服务器,比如源服务器上一级是代理服务器,然后代理服务器才与客户端通信,这时客户端重定向就会导致客户端与代理服务器之间需要 2次消息传递,如下图:
如果重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数了,如下图:
而且当代理服务器知晓了重定向规则后,可以进一步减少消息传递次数,如下图:
除了 302 重定向响应码,还有其他一些重定向的响应码,你可以从下图看到:
其中, 301 和 308 响应码是告诉客户端可以将重定向响应缓存到本地磁盘,之后客户端就自动用 url2替代 url1 访问服务器的资源。
合并请求
如果把多个访问小文件的请求合并成一个大的请求,虽然传输的总资源还是一样,但是减少请求,也就意味着减少了重复发送的 HTTP 头部。
另外由于 HTTP/1.1 是请求响应模型,如果第一个发送的请求,未收到对应的响应,那么后续的请求就不会发送(PS:HTTP/1.1 管道模式是默认不使用的,所以讨论 HTTP/1.1 的队头阻塞问题,是不考虑管道模式的),于是为了防止单个请求的阻塞,所以一般浏览器会同时发起 5-6 个请求,每一个请求都是不同的 TCP 连接,那么如果合并了请求,也就会减少 TCP 连接的数量,因而省去了 TCP 握手和慢启动过程耗费的时间。
接下来,具体看看合并请求的几种方式。
有的网页会含有很多小图片、小图标,有多少个小图片,客户端就要发起多少次请求。那么对于这些小图片,我们可以考虑使用 CSS lmage Sprites 技术把它们合成一个大图片,这样浏览器就可以用一次请求获得一个大图片,然后再根据 CSS 数据把大图片切割成多张小图片。
这种方式就是通过将多个小图片合并成一个大图片来减少 HTTP 请求的次数,以减少 HTTP 请求的次数从而减少网络的开销。
除了将小图片合并成大图片的方式,还有服务端使用webpack 等打包工具将js、css 等资源合并打包成大文件,也是能达到类似的效果。
另外,还可以将图片的二进制数据用 base64 编码后,以URL的形式嵌入到 HTML 文件,跟随 HTML文件一并发送.
<image src="data:image/png;base64,iVBORWOKGgOAAAANSUhEUgAAAPOAAAFKC
7M9WrAAAACXBIWXMAA .../>
这样客户端收到 HTML 后,就可以直接解码出数据,然后直接显示图片,就不用再发起图片相关的请求这样便减少了请求的次数。
可以看到,"合并请求的方式就是合并资源,以一个大资源的请求替换多个小资源的请求"
但是这样的合并请求会带来新的问题,当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整的大资源文件,这显然带来了额外的网络消耗。
延迟发送请求
不要一口气吃成大胖子,一般 HTML 里会含有很多 HTTP 的 URL,当前不需要的资源,我们没必要也获取过来,于是可以通过「按需获取」的方式,来减少第一时间的 HTTP 请求次数。
请求网页的时候,没必要把全部资源都获取到,而是只获取当前用户所看到的页面资源,当用户向下滑动页面的时候,再向服务器获取接下来的资源,这样就达到了延迟发送请求的效果。
这期就到这里,下期见!