Web 开发者的 HTTP/2 性能优化指南

本文讲的是Web 开发者的 HTTP/2 性能优化指南,


HTTP/2改变了Web开发者优化网站的方式。在HTTP/1.1中,为了压缩5%的页面加载速度,人们会通过雪碧图、内联代码、细分域名、合并代码等方式,来想方设法地优化TCP连接和HTTP请求。

HTTP/2带来了些许便利。一般网站无需复杂的构建和部署流程即可获得30%的性能提升。在这篇文章中,我们会讨论HTTP/2下网站优化的最佳实践。

HTTP/1.1中的Web优化

HTTP/1.1中大多数的网站性能优化技术都是减少向服务器发起的HTTP请求数。浏览器可以同时建立有限个TCP连接,而通过这些连接下载资源是一个线性的流程:一个资源的请求响应返回后,下一个请求才能发送。这被称为线头阻塞。

因此,Web开发者开始将尽可能多的资源塞进一个连接中,并寻找其他办法来避免浏览器出现线头阻塞。在HTTP/2中,这样的实践事实上会增加页面的加载时间。

HTTP/2下的Web优化新观念

HTTP/2的优化需要不同的思维方式。Web开发者应该专注于网站的缓存调优,而不是担心如何减少HTTP请求数。通用的法则是,传输轻量、细粒度的资源,以便独立缓存和并行传输。

这种转变的出现是因为HTTP/2的多路复用和头部压缩特性。多路复用使得不同的请求共用一个TCP连接,允许多个资源并行下载,避免建立多个连接带来不必要的额外开销。它消除了HTTP/1.1中的线头阻塞问题。头部压缩进一步减少了多个HTTP请求的开销,因为每个请求开销都小于未压缩的等价HTTP/1.1请求。

HTTP/2还有两个改变会影响到你的Web优化:流优先级和服务端推送。前者允许浏览器指定接受资源的顺序,后者允许服务端主动发送额外的资源。为了尽可能利用这些特性,Web开发者需要抛弃一些HTTP/1.1中形成直觉的最佳实践。

HTTP/2 Web优化最佳实践

停止合并文件

在HTTP/1.1中,Web开发者往往将整个网站的所有CSS都合并到一个文件。类似的,JavaScript也被压缩到了一个文件,图片被合并到了一张雪碧图上。合并CSS、JavaScript和图片极大地减少了HTTP的请求数,在HTTP/1.1中能获得显著的性能提升。

但是,在HTTP/2中合并文件不再是一项最佳实践。虽然合并依然可以提高压缩率,但它带来了代价高昂的缓存失效。即使有一行CSS改变了,浏览器也会强制重新加载你 所有的 CSS声明。

另外,你的网站不是所有页面都使用了合并后的CSS或JavaScript文件中的全部声明或函数。被缓存之后倒没什么关系,但这意味着在用户第一次访问时这些不必要的字节被传输、处理、执行了。HTTP/1.1中请求的开销使得这种权衡是值得的,而在HTTP/2中这实际上减慢了页面的首次绘制。

Web开发者应该更加专注于缓存策略优化,而不是压缩文件。将经常改动和不怎么改动的文件分离开来,就可以尽可能利用CDN或者用户浏览器缓存中已有的内容。

停止内联资源

内联资源是文件合并的一个特例。它指的是将CSS样式表、外部的JavaScript文件和图片直接嵌入HTML页面中。例如,如果你的网页如下所示:

<html>
  <head>
    <link rel="stylesheet" href="/style.css">
  </head>
  <body>
    <img src="logo.png">
    <script src="scripts.min.js"></script>
  </body>
</html>

你可以通过内联工具获得下面的代码:

<html>
  <head>
    <style>

      body {
        font-size: 18px;

        color: #999;
      }
    </style>
  </head>
  <body>
    <img src="data:image/png;base64,Rw0KGgoAAAANSUhEUgAAAEAABA...">
    <script>console.log('Hello, World!');</script>
  </body>
</html>

在极端情况下,这确实能够减少给定网页的HTTP请求数。但是,和文件合并一样,HTTP/2优化时你不应该内联文件。

内联意味着浏览器不能缓存单个的资源。如果你将所有页面使用的CSS声明嵌入了每一个HTML文件,这些文件每次都要从服务端获取。这导致用户在访问任何页面时都要传输额外的字节。

内联同样会破坏流优先级。如果你的CSS、JavaScript和图片嵌入在HTML中,你实际上将它们的优先级提升到了HTML内容相同的级别。这意味着浏览器无法按照偏好的顺序请求资源,潜在地增加了首次渲染时间。

与其内联资源,Web开发者应该用好HTTP/2的服务端推送功能。服务端推送使得你的Web服务器可以告诉客户端:“稍等,你刚请求的HTML页面过会渲染时会用到这些图像和CSS文件”。理论上这和内联资源效果相同,但它不会破坏流优先级,并允许你充分利用CDN和用户的本地浏览器缓存。

停止细分域名

细分域名是让浏览器建立更多TCP连接的通常手段。浏览器限制了单个服务器的连接数量,但是通过将网站上的资源切分到几个域上,你可以获得额外的TCP连接。它避免了线头阻塞,但也带来了显著的代价。

细分域名在HTTP/2中应该避免。每个细分的域名都会带来额外的DNS查询、TCP连接和TLS握手(假设服务器使用不同的TLS证书)。在HTTP/1.1中,这个开销通过资源的并行下载得到了补偿。但在HTTP/2中就不是这样了:多路复用使得多个资源可以在一个连接中并行下载。同时,类似于资源内联,域名细分破坏了HTTP/2的流优先级,因为浏览器不能跨域比较优先级。

如果你目前使用了域名细分但希望利用HTTP/2,你不必重构你的整个代码库。在我们博客上的一篇文章域名细分和SPDY混用中提到,浏览器能够识别使用同一个TLS证书的多个服务器。一旦你这样做了,浏览器会重用多个服务器之间的SPDY或HTTP/2请求。这仍然会导致多个DNS查询,但如果你同时想在HTTP/1.1和HTTP/2下获得最佳性能,这算是一个优雅的妥协之举。

一些最佳实践依然有效

幸运的是,HTTP/2没有改变所有的Web优化方式。一些HTTP/1.1中的最佳实践在HTTP/2中依然有效。剩下的文章讨论了这些技巧,无论你在HTTP/1.1还是HTTP/2优化都能用上。

减少DNS查询时间

在浏览器可以请求网站资源之前,它需要通过域名系统(DNS)获得你的服务端IP地址。直到DNS响应前,用户看到的都是白屏。HTTP/2优化了Web浏览器和服务器之间的通信方式,但它不会影响域名系统的性能。

因为DNS查询的开销可能会很昂贵,尤其是当你从根名字服务器开始查询时,最小化网站使用的DNS查询数仍然是一个明智之举。使用HTML头部的<link rel='dns-prefetch' href='...' />可以帮助你提前获取DNS记录,但这不是万能的解决方案。

使用CDN

光在地球表面绕行一圈需要大约130毫秒。这个延迟你 无法 避免——物理使然。光缆和无线连接的不完善之处,以及全球因特网的拓扑结构,使得你电脑上的一个网络包至少要300-400毫秒才能传输到半个世界外的服务器。用户可以觉察到100毫秒的延迟,唯一克服物理规律的办法就是将你的Web资源通过CDN放在地理上更靠近来访者的服务器节点上。

利用浏览器缓存

你可以进一步利用内容分发网络,将资源存储在用户的本地浏览器缓存中,除了产生一个304 Not Modified响应之外,这避免了任何形式的数据在网络上传输。

最小化HTTP请求大小

尽管HTTP/2的请求使用了多路复用技术,在线缆上传输数据仍然需要时间。同时,减少需要传输的数据规模同样会带来好处。在请求端,这意味着尽可能多地最小化cookie、URL和查询字符串的大小。

最小化HTTP响应大小

当然了,另一端也是这样。作为Web开发者,你会希望服务端的响应尽可能的小。你可以最小化HTML、CSS和JavaScript文件,优化图像,并通过gzip压缩资源。

减少不必要的重定向

HTTP 301和302重定向在迁移到新平台或者重新设计网站时难以避免,但如有可能应该被去除。重定向会导致一圈额外的浏览器到服务端往返,这会增加不必要的延迟。 你应该特别留意重定向链,上面需要多个重定向才能到达目的地址。

像301和302这样的服务端重定向虽不理想,但也不是世界上最糟的事情。它们可以在本地被缓存,所以浏览器可以识别重定向URL,并且避免不必要的往返。元标签中的刷新(如<meta http-equiv="refresh"...)在另一方面开销更大,因为它们无法被缓存,而且在特定浏览器中存在性能问题。

结论和警示

以上寥寥数语介绍了HTTP/2的Web优化。防止文件合并、资源内联和域名细分不仅能够加速网站,还使得构建和部署流程更加简单。

不过,还有一些需要警醒的地方。大多数的服务器、内容分发网络(包括CloudFlare)和现有的应用还不支持服务端推动。服务器和CDN会迅速跟进,但为了让你的应用享受到服务端推送的好处,你还需要对代码库进行一些修改。

同时记住,HTTP/2的性能提升取决于你服务的内容。比如,依赖于外部资源的网站相比于那些HTTP请求更少的网站,会从HTTP/2的多路复用获得更大的性能提升。





原文发布时间为:2015年12月28日


本文来自合作伙伴掘金,了解相关信息可以关注掘金网站。

时间: 2024-10-01 10:59:27

Web 开发者的 HTTP/2 性能优化指南的相关文章

Jquery 学习笔记(二)jQuery性能优化指南

Jquery 学习笔记(二) -jQuery性能优化指南 2009年11月30日 一 作者:   邦畿千里   1,总是从ID选择器开始继承 在jQuery中最快的选择器是ID选择器,因为它直接来自于JavaScript的getElementById()方法. 例如有一段HTML代码: <div id="content"> <form method="post" action="#"> <h2>交通信号灯<

jQuery 性能优化指南(2)_jquery

4,对直接的DOM操作进行限制   这里的基本思想是在内存中建立你确实想要的东西,然后更新DOM . 这并不是一个jQuery最佳实践,但必须进行有效的JavaScript操作 .直接的DOM操作速度很慢. 例如,你想动态的创建一组列表元素,千万不要这样做,如下所示: var top_100_list = [...], // 假设这里是100个独一无二的字符串 $mylist = $("#mylist"); // jQuery 选择到 <ul> 元素 for (var i=

jQuery性能优化指南

jQuery性能优化指南,可以从以下12个方向考虑. 1,总是从ID选择器开始继承 2,在class前使用tag(标签名) 3,将jQuery对象缓存起来(在多次使用是,用一个中间变量代替,而不是总是用选择器)   4,对直接的DOM操作进行限制 5,注意尽量减少事件冒泡 6,推迟到 $(window).load   7,压缩JavaScript 8,尽量使用ID代替Class. 9,给选择器一个上下文   10,慎用 .live()方法(应该说尽量不要使用) 11,子选择器和后代选择器   1

jQuery 性能优化指南 (1)_jquery

1,总是从ID选择器开始继承 在jQuery中最快的选择器是ID选择器,因为它直接来自于JavaScript的getElementById()方法. 例如有一段HTML代码: 复制代码 代码如下: <div id="content"> <form method="post" action="#"> <h2>交通信号灯</h2> <ul id="traffic_light"&

jQuery 性能优化指南(3)_jquery

8,尽量使用ID代替Class.   前面性能优化已经说过,ID选择器的速度是最快的.所以在HTML代码中,能使用ID的尽量使用ID来代替class.看下面的一个例子: // 创建一个list var $myList = $('#myList'); var myListItems = '<ul>'; for (i = 0; i < 1000; i++) {      myListItems += '<li class="listItem' + i + '">

IIS 网站服务器性能优化指南_win服务器

但配置.优化IIS的性能,使得网站访问性能达到最优状态却不是一件简单的事情,这里我就介绍一下如何一步一步的优化你的IIS服务器. 服务器端环境,我们以Windows Server 2003的IIS6.0为例,客户端环境为Mozilla Firefox 3.0,同时安装Yahoo的YSlow扩展. YSlow是Yahoo开发者团队发布的一款基于Firebug的插件.用于分析网页,并根据一些高性能网站的规则进行相应的评级打分,对于网页性能优化有很好的帮助作用,告诉你那些部分影响了你的网页速度,并告诉

移动HTML 5前端性能优化指南

  前端工程师的菜!最近移动Html 5越来越火,想有一个体验流畅的Html 5 应用,这篇优化指南就别放过咯.腾讯的同学将关键的注意点与优化方法都总结出来,全文高能干货,非常值得深度学习 >>> 概述 PC优化手段在Mobile侧同样适用 在Mobile侧我们提出三秒种渲染完成首屏指标 基于第二点,首屏加载3秒完成或使用Loading 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB Mobile侧因手机配置原因,除加载外渲染速度也是优化重点 基

Lua性能优化指南

说明 本文主要取材于Lua Programming Gems一书的第二章Lua Performance Tips, 原书试读章节可点击这里下载 测试代码的运行环境均为Raspberry Pi 3, Lua 5.1.5 性能优化的基本原则 能不优化则不优化 先量化再优化:高手和菜鸟之间的区别不在于高手对于需要优化的点直觉更准,而是高手更清楚自己的经验和感觉都是不可靠的,只能依靠测试数据来定位性能瓶颈. 多用局部变量 就表达式 a = a + b而言,当a, b都是局部变量时,Lua虚拟机只需要执行

Java性能优化指南 | 江南白衣

正文 来了唯品会一年多,不少时间花在与服务化框架.业务应用的性能的缠斗上. 前几天正好趁着中生代技术的十月十城技术沙龙,把脑海中关于性能优化的记忆全部理了一遍....讲完回家,又本着认真严谨的态度再理了一遍,终于成为现在这份66页的PPT. 各位客官,1.8版内容略有增减,超链接也已修好,请重新下载. 范围 应用性能,受操作系统参数,三方类库选择,数据库查询,甚至压测工具如JMeter本身调优的影响. 本次分享只着重在三方面: JVM的调优 代码的调优 定位性能问题的工具 基本原则 网上如此多新