vlambda博客
学习文章列表

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

作者丨kyrieliu

来源丨经授权转自 劉凯里(ID:kkkyrieliu)


前段时间面试了一位候选人,当我问到前端性能优化的常用手段时,候选人很笃定地说雪碧图,能减少页面请求数量,而且她经常在项目中使用。 

但事实是,前端早就不用雪碧图了。

这篇文章会对前端性能优化宝典「雅虎军规」中关于「减少 HTTP 请求」的部分进行解读,并从 HTTP 协议的层面说明一个问题:现代前端工程中为什么不需要过于关注 HTTP 请求数了?


从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?
雅虎军规有言:终端用户的等待时间中,有 80% 都耗在了前端上。而这些时间消耗中,大部分都用来加载页面所需的资源,比如:图片、视频、样式、脚本等。在这个问题上,终极的解决思路是「通过减少页面资源数来控制 HTTP 请求数」,而 HTTP 请求越少,呈现给用户的页面也就会越快。
毕竟,还记得这个听起来就很麻烦的过程吗 👇

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?


但,总不能为了页面快速渲染,只把最简单的文字内容呈现给用户吧,就算咱们前端愿意,产品经理和设计师也是一百个不愿意。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

伴随着这几年网络内容的爆炸式发展,在终端呈现更多丰富的内容是一个不可逆的发展趋势,所以这个时代的前端工程师要在兼顾页面内容丰富基础上,不断加速网页的响应速度。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

接下来会介绍一些上古时代的、关于减少请求数的前端性能优化法则(「雅虎军规」是在 2006 年底提出的),以及这些法则是为何在现代前端工程被废弃的。

文件合并

文件合并,顾名思义,是把多个文件合并成一个文件(JavaScript 或 CSS),这么做的目的自然是为了减少文件的数量,从而减少 HTTP 请求的数量。比如我们现在有一个页面,页面上引用了来自不同域名的多个 JS 和 CSS,那么初始化这个页面时,需要发起的 HTTP 请求数就是这些文件个数的总和。之后有了 grunt、gulp 等工具的诞生,开发者在构建时会把多个同类型的文件打包为一个大文件,这样只需要发起很少的请求数就能获得相同内容的文件(或者说是“文件集合”)。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

雪碧图

雪碧图原名是 「CSS Sprites」,原意是「精灵」,但恰好和「雪碧」的英文名一样,所以在中国大家都称其为「雪碧图」。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

雪碧图的原理也很简单,把页面上(或是整个网站)上要用到的小图片合并成一张大图片,通过 css 的 background-image 和 background-position 来使用对应的图片。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

但,由于这个概念提出的年代比较早,还没有诸如 gulp、webpack 之类的自动化构建工具,前端工程师们为了提高页面加载的性能,通常都需要自己制作雪碧图,可谓非常痛苦。
和雪碧图相似,还有个方案,叫做「映射图」。本质还是把很多张图片拼在一起来减少 HTTP 请求的数量。和雪碧图不同的是,映射图提倡把页面的所有原质量图片拼在一起。但由于使用场景有限(一般只能用在连贯图片展示的场景),所以很快就被抛弃了。

Base64 图片

在 Yahoo 军规中,base64 图片称作「inline images」。Base64 图片的本质是通过对一张图片进行 base 64 编码,生成的字符串可以用来在 html、css 文件中代替图片地址。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

但是和其他优化手段不同的是,base64 不一定真的就意味着「优化」:当进行 base64 编码时,得到的字符串往往非常长,会变相增加 html 或 css 的体积,所以在使用时需要做一下权衡。一般我们在 webpack 工程中,会指定 8kb 以下的图片转用 base64 图片的形式。

但是,早就没必要这么玩了

在现代前端工程中,其实不太有人会 care 「合并文件以减少 HTTP 请求数」这个优化手段了,或者说,随着 HTTP 协议的更新换代,它甚至都不配作为一个「性能优化手段了」。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

还记得 TCP 连接三次握手和四次挥手的过程吗?没关系,忘了的话我再贴一遍图。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

每一个 HTTP 请求在发送出去之前,都会经历一次 TCP 三次握手的过程,当数据传输完毕,又进行一次四次挥手的过程,是不是贼麻烦?

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

上面这张图,没有错,但是(我又要说但是了),这已经是将近 20 年之前的事情了。回顾一下 HTTP 协议的发展史我们发现,完整的 HTTP 协议(也就是 HTTP 1.0)诞生于 1996 年,过了三年后就升级为 HTTP 1.1,到了 2015 年,再次升级为 HTTP 2.0。其实到 2021 年的今天,HTTP 已经进入 3.0 时代了。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

严格意义上来说,合并文件这种性能优化手段,在 HTTP 1.1 推出后,就应该受到质疑了。为什么呢?且看下面这张图:

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

HTTP 1.1 版本默认支持长连接(Connection:keep-alive)和流水线请求(Pipelining),也就是说,多个 HTTP 请求可以依次共享同一个 TCP 连接,大大减少了建立 TCP 连接时的消耗和延迟。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

到了 2015 年,HTTP 2.0 横空出世,带着多路复用的光环来了,不仅解决了 HTTP 1.1 流水线请求会造成的请求阻塞的问题,更重要的是,多路并行,更快了

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

下图是在相同的网路状况下,HTTP 1.1 和 HTTP 2.0 的直观对比图。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

综上所述,在现代前端工程里,没有必要做这种「合并文件以减少 HTTP 请求」的“优化”,相反的,现在的前端应用都很大,反而需要用到「分包加载」和「懒加载」等手段,减少每个静态文件的实际体积,这样才能获得更快的下载速度以及在浏览器端获得更快的解析速度。

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

1、

2、

3、

4、

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

从 HTTP 协议求解:为什么我们越来越不需要雪碧图了?

点分享

点点赞

点在看