假如 HTTP/2 已经普及

发布于 2025-06-09 11:45:12 字数 0 浏览 0 评论 0

一项新技术的来临,总是自上而下的,从标准推出到软硬件支持再到实施,然后普及,这中间总要经历漫长的更新之路。本文我们跨过慢慢长夜,直接讨论 假如 HTTP/2 已经普及,我们前端跟现在会有哪些不同,也许你会觉得太操之过急,没必要这么早开始讨论,然而回看历史,各种技术总会在我们不经意间闯入我们的工作,更新我们的生活,与其措手不及不如提早部署,只有心怀远方我们才能走的更远。

如果不清楚什么是 HTTP/2 的可以先了解下,前面有一篇图文并茂的介绍 HTTP/2 的文章 传送门

现状

去年(2015 年 5 月)HTTP/2 标准正式发布,各大浏览器,服务器厂商都开始大面积支持这一标准,国内外各大应用网站也都开始纷纷踏入 HTTP/2 的阵营,Facebook、Google、Twitter、 国外亚马逊 (部分请求)、 天猫 (部分请求)、 淘宝 (部分请求),还有一些小型站点比如 ISUX 等。

一些大型公司,因为架构体系原因导致迁移带来的阵痛,拖累了升级 HTTP/2 的进度,有心无力,反而一些小型网站,架构合理的公司升级起来更迅速一些,提早体验到了 HTTP/2 带来的快感。

现在软硬件都已基本到位,“趟雷”的已经探好了路,就等后续大军杀到。买房子的时候,都说早买早享受,HTTP/2 也一样,房子买晚了,HTTP/2 你还要再等么,你要做的其实就是尽早升级尽快享受。

HTTP/2 已经普及

也许 HTTP/2 真正全面普及,可能还得一两年,或者是三四年,那么我就直接穿越到未来的一天, 假设 HTTP/2 已经普及了,那么很快会有很多问题摆在我们面前:以前的架构还需要么?如何组织代码更能合理支持 HTTP/2?我们十几年的优化总结还有用么?雅虎军规还是我们的优化的标准么?

在讨论这之前我们再来回顾下,HTTP/2 给我们提供了什么。

HTTP/2 给我们的好处

  • 多路复用 :一次 TCP 握手,多个同域并行请求,请求和响应同时发送接受,然后再拼装组合,不阻塞;
  • 优先级和依赖性(Priority) :可以请求的时候告知服务器端,资源分配权重,优先加载重要资源;
  • 服务器推送(Server Push) :根据客户端需求,服务端主动推送资源,减少请求耗时;

概念网上大把,我们直接用几个例子来分析,把概念直接体现在实例中:

多路复用

Demo HTTP/2 和 HTTP1.1 图片请求对比

示例分别用 169 张图片拼合成一整张大图,第一组图片请求为 HTTP1.1,第二组请求为 HTTP/2,下面我截取的加载过程的动画。

HTTP1.1 vs HTTP/2 请求速度

http1 vs http2

同时导出了 http1.1-images.harhttp2-images.har 文件,我们借助第三方服务 HAR Viewer 来看下,请求细节:

HAR 文件 是以.har 结尾的 JSON 文件,用于记录了 HTTP 请求的详细信息。 这里 有详细介绍,可以在 Chrome 中开发者工具的 Network 中点右键导出.har 文件。

下图就是 HAR 文件分析的截图:

HTTP1.1

http1.1

上图为 HTTP1.1 的图片请求,请求基本上是 6 个一组,然后 6 个完成后再 串行请求 下一组。

HTTP/2

http2

从上面的部分截图,可以清晰看到,所有请求基本都是并行请求,由于数据发送量较大,所以会有“等待”,这里的等待应该是数据流在客户端或服务器端重新组合的过程,正是因为这样所以单个请求时间相对更长。但是就整体速度来说 HTTP/2 为 1.53s, HTTP1.1 为 2.47s。速度快了近 40%

http2

上面这张图也是 HTTP/2 的一部分,从另一面也可以体现出,并行请求的短板,就是 木桶理论 。所以请求尽量做到细粒度,能更快返回数据。

PS:当然我只截取了比较能突出差别的图,具体的完整版可以点进 HAR Viewer ,然后拖进去我们上面提供的 har 文件。

这就是 HTTP/2 为我们带来的最大的好处 多路重复

服务器推送(Server Push)

Demo 普通加载 & Demo Server Push

示例分别用 Server Push 推送,和传统的加载,带来的性能上的差异,同时我也导出了两个 HAR 文件,如果需要可自行下载 serverpush.harnomalrequest.har

下面是这两个文件的请求截图(下面是 Server Push, 上面是普通 HTTP/2 的请求):

server push

HTTP/2 Server Push 和 普通请求相比,去掉了请求阶段,直接返回数据(Content Download),数据获取速度更快,而且 push 中可以嵌入逻辑,并且请求还可以进行缓存。

贴一小段代码,下面的代码为请求接口的时候,主动推送 zepto 代码给客户端的核心代码:

router.get('/serverpush', function (ctx, next){
  var zepto = fs.readFileSync(resolve(root, 'public/js/zepto.js'), { encoding: 'UTF-8' })
  var html = fs.readFileSync(resolve(root, 'public/item2_1.html'), { encoding: 'UTF-8' })
  ctx.res.push('/zepto.js', options, function(err, stream){
      if (err) return;
      zlib.gzip(zepto,function(err, buf){
        stream.end(buf)
      })
  });
  ctx.body = html
})

这里可以查看完整的 Server Push 代码

关于优先级和依赖性(Priority)

优先级的设置可以看下 这一篇文章 ,通过设置请求资源的 Pripority,达到资源获取的优先级。

没有设置 Pripority

pripority

设置 CSS 和 JS 的 Pripority 后

pripority

设置 Pripority 后,CSS 和 JS 明显速度更快了,但是代价是牺牲了图片的部分请求的速度。

通过上面的示例,牛 B 闪闪的 HTTP/2 已经在屏幕上熠熠生辉了。

那么回过头来再看看我们以前针对 HTTP1.1 的优化,我觉得很多其实都是应对 HTTP1.1 不足的 HACK,HTTP/2 中这些都已经不是问题了,所以 HACK 可以去掉了,比如下面这些。

雪碧图(Sprite)

这里同样我写了一个测试示例 Demo 雪碧图 & Demo 没有雪碧图 ,如下图上面为使用雪碧图的页面请求, 下面是普通的请求页面。

Sprite

由于木桶理论,在非雪碧图请求中,由于最后返回速度决定于那个最慢的请求,所以非雪碧图单张 524B 的文件速度,跟雪碧图 6.9K 速度比,还慢一些,虽然如此,我们再看 onload 事件触发时间,因为多路复用的特性,虽然请求超过 4 倍但是请求总时长并不是多 4 倍,而是多了 119ms(1-2 张图片的请求时长),而且根据请求更多其实差距不会体现在请求的多少,而只会体现在请求的响应时间和下载数据的大小,而雪碧图占用的请求应该都是很小的,所以合并与否其实不明显,再考虑到雪碧图的维护成本,其实就 HTTP/2 来说并不推荐再使用雪碧图了。(不过为了兼容 HTTP1.1,其实现阶段多版本并存的时候还是建议保留,不用再单独处理逻辑)

HTTP1.1 中,所有为了减少请求而做出的 HACK,在 HTTP/2 中都已经不再是性能优化考虑的主要点了。

分域名

HTTP1.1 时代,我们经常会用多个域名来做请求优化,因为浏览器同域名下会有并行请求数限制(根据浏览器不同 2-8 个,比如 IE6 只有两个),然而 DNS 解析又得额外花时间,所以以前对域名的个数还需要根据各自网站找一个平衡点。HTTP/2 就不用理会这个了,因为多路复用,并行请求不再是瓶颈,收敛了域名后还能减少 DNS 解析时间,所以 HTTP/2 中我们不用再细分域名了。

接口请求

HTTP1.1 的时候,我们经常会根据当前的页面,将请求合并成一个。HTTP/2 中可以更细粒度的组合你的接口,不用再根据某个页面所需数据,来组合一个专门的无意义的接口了(不用合并请求),不怕请求多,就怕单个请求太慢。

内联资源

有人说 Server Push 就是另外一种形式的内联,其实不是,内联太 Low 了,完全无法跟它来比较。

首先我们来回顾下,HTTP1.1 时代,我们为什么要内联,因为我们希望减少请求,我们为了加快首页的渲染速度,甚至会把首页第一屏的样式内联到 HTML 中,一起返回,加速首屏渲染。然而当有人想改动首屏任何内容,无论多小都得重新替换掉整个页面。

在 HTTP/2 下我们可以通过推送的方式给你想要的资源,跟你的 HTML 请求一块儿返回给你,不仅如此,push 的内容还可以进行缓存,多页面共享。

兼容

先来看下兼容和各版本客户端占有率统计

数据来自 caniuse

can i use

PC 浏览器占有率 数据来自百度统计

pc

IOS & Andorid 操作系统版本占有率 数据来自友盟 2016 年 6 月 5 日统计数据,红色为支持版本

占有率

结论:PC 端 Chrome 占有率已经近 40%,移动 Android5.0 以上占 26%,IOS9.2 占 60% 以上,所以保守估计,至少现阶段升级 HTTP/2,就已经能保证 1/3 的人能享受到 HTTP/2 带来的快感,而且这个数字随着时间会快速增长。 同时 HTTP 是支持向前兼容的,如果你的浏览器不支持 HTTP/2 可以降级成 HTTP1.1,而且服务端也可以通过请求来判断客户端是不是支持 HTTP/2,如此一来我们可以通过请求来返回 HTTP/2 版本的网站。这样就能尽量让更多人体验到 HTTP/2 的一些特性了,并且不影响其他人的使用。

以前当我们无法快速提升网络速度,无法改变一些硬件上的性能,能做的可能只有代码阶段,然而现在有了一种强劲的性能提升方案,那就是 HTTP/2,也是目前性价比最高的性能提升方案了。

当然,如果你还是很纠结 HTTP/2 的兼容性,推荐另一个 HTTP 协议 SPDY ,虽然 HTTP/2 的出现,迟早会替换掉 SPDY,但是作为 HTTP/2 的前身,兼容性会更好,比如淘宝,天猫都已经支持 SPDY 了,个人觉得替换 SPDY 就是时间问题,所以还是推荐从 HTTP/2 开始吧。

不过既然提到就先看看兼容性:

兼容性

SPDY 不是本文重点就推荐一些资料:

本文的 Demo 及 测试代码

本文参考资料

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

断爱

暂无简介

文章
评论
709 人气
更多

推荐作者

演出会有结束

文章 0 评论 0

佚名

文章 0 评论 0

演员

文章 0 评论 0

github_Ya3wWzbdC

文章 0 评论 0

江南

文章 0 评论 0

美煞众生

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。