3.2 HTTP/1.1 如何优化?
避免发送 HTTP 请求
缓存技术:通过HTTP 协议的头部针对缓存的字段协商。会将一些具有重复性的 HTTP 「请求 - 响应」缓存在本地,下次直接读取。
客户端会把第一次请求以及响应的数据保存在本地磁盘上,其中将请求的 URL 作为 key,而响应作为 value,两者形成映射关系。
这样当后续发起相同的请求时,就可以先在本地磁盘上通过 key 查到对应的 value,也就是响应,如果找到了,就直接从本地读取该响应。
服务器在发送 HTTP 响应时,会估算一个过期的时间,并把这个信息放到响应头部中,这样客户端在查看响应头部的信息时,一旦发现缓存的响应是过期的,则就会重新发送网络请求。
如果客户端从第一次请求得到的响应头部中发现该响应过期了,客户端重新发送请求,会在请求的 Etag 头部带上第一次请求的响应头部中的摘要,当服务器收到请求后,会将本地资源的摘要与请求中的摘要做个比较。
- 如果不同,那么说明客户端的缓存已经没有价值,服务器在响应中带上最新的资源。
- 否则服务器仅返回不含有包体的
304 Not Modified响应,告诉客户端仍然有效,这样就可以减少响应资源在网络中传输的延时。
减少 HTTP 请求次数
减少重定向请求次数
重定向请求:服务器的资源出现迁移等原因从 url1 移至 url2,客户端不知情,它还是继续请求 url1,这时服务器通过 302 响应码和 Location 头部,告诉客户端该资源已经迁移至 url2 了,于是客户端需要再发送 url2 请求以获得服务器的资源。
那如果重定向请求越多,那么客户端就要多次发起 HTTP 请求,会越降低网络性能。且客户端可能直接请求的代理服务器,通过中转请求次数更多。
如果重定向的工作交由代理服务器完成,就能减少 HTTP 请求次数了。
而且当代理服务器知晓了重定向规则后,可以进一步减少消息传递次数。
合并请求
如果把多个访问小文件的请求合并成一个大的请求,虽然传输的总资源还是一样,但是减少请求,也就意味着减少了重复发送的 HTTP 头部。
有的网页会含有多个小图片,每个图片都要发一次请求。那么对于这些小图片,我们可以考虑使用 CSS Image Sprites 技术把它们合成一个大图片,这样浏览器就可以用一次请求获得一个大图片,然后再根据 CSS 数据把大图片切割成多张小图片。
还有服务端使用 webpack 等打包工具将 js、css 等资源合并打包成大文件,也是能达到类似的效果。
但是这样的合并请求会带来新的问题,当大资源中的某一个小资源发生变化后,客户端必须重新下载整个完整的大资源文件,这显然带来了额外的网络消耗。
延迟发送请求
一般 HTML 里会含有很多 HTTP 的 URL,当前不需要的资源,我们没必要也获取过来,于是可以通过「按需获取」的方式,来减少第一时间的 HTTP 请求次数。
比如当用户向下滑动页面的时候,再向服务器获取接下来的资源,这样就达到了延迟发送请求的效果。
如何减少 HTTP 响应的数据大小?
对响应的资源进行压缩,这样就可以减少响应的数据大小。
无损压缩
无损压缩:资源经过压缩后,信息不被破坏,还能完全恢复到压缩前的原样,适合用在文本文件、程序可执行文件、程序源代码。
首先,我们针对代码的语法规则进行压缩,因为通常代码文件都有很多换行符或者空格,这些是为了帮助程序员更好的阅读,但是机器执行时并不要这些符,把这些多余的符号给去除掉。
接下来,就是无损压缩了,需要对原始资源建立统计模型,利用这个统计模型,将常出现的数据用较短的二进制比特序列表示,将不常出现的数据用较长的二进制比特序列表示,生成二进制比特序列一般是「霍夫曼编码」算法。
gzip 就是比较常见的无损压缩。客户端支持的压缩算法,会在 HTTP 请求中通过头部中的 Accept-Encoding 字段告诉服务器:
Accept-Encoding: gzip, deflate, br服务器收到后,会从中选择一个服务器支持的或者合适的压缩算法,然后使用此压缩算法对响应资源进行压缩,最后通过响应头部中的 Content-Encoding 字段告诉客户端该资源使用的压缩算法。
Content-Encoding: gzipgzip 的压缩效率相比 Google 推出的 Brotli 算法还是差点意思,也就是上文中的 br,所以如果可以,服务器应该选择压缩效率更高的 br 压缩算法。
有损压缩
此方法压缩,解压的数据会与原始数据不同但是非常接近。主要将次要的数据舍弃,牺牲一些质量来减少数据量,这种方法经常用于压缩多媒体数据,比如音频、视频、图片。
可以通过 HTTP 请求头部中的 Accept 字段里的「q 质量因子」,告诉服务器期望的资源质量。
Accept: audio/*; q=0.2, audio/basic关于图片的压缩,目前压缩比较高的是 Google 推出的 WebP 格式,它与常见的 Png 格式图片的压缩比例对比如下图:

可以发现,相同图片质量下,WebP 格式的图片大小都比 Png 格式的图片小,所以对于大量图片的网站,可以考虑使用 WebP 格式的图片,这将大幅度提升网络传输的性能。
关于音视频的压缩,音视频主要是动态的,每个帧都有时序的关系,通常时间连续的帧之间的变化是很小的。
比如,一个在看书的视频,画面通常只有人物的手和书桌上的书是会有变化的,而其他地方通常都是静态的,于是只需要在一个静态的关键帧,使用增量数据来表达后续的帧,这样便减少了很多数据,提高了网络传输的性能。对于视频常见的编码格式有 H264、H265 等,音频常见的编码格式有 AAC、AC3。
