1.1 理解Web性能
身为开发人员,你或许听说过Web性能,但是对它了解不深;或许你已经使用过其中的一些技术快速解决了问题;又或许你已经很熟悉这个主题了,希望通过本书发现一些新的技巧,以进一步优化自己的网站。
别担心!无论你在这个领域是新手还是老将,本书都能帮助你更好地理解Web性能,了解提升网站性能的方法,以及如何将这些方法应用于你的网站。
不过,在讨论Web性能的细节之前,必须先透彻理解我们想要解决的问题。
1.1.1 Web性能和用户体验
高性能的网站可以改善用户体验。你可以通过提高网站速度来加快内容的传输,从而改善用户体验。此外,当网站加载速度更快时,用户更有可能关注网站上的内容。没有任何一个用户愿意浏览加载缓慢的网站。
有数据表明,网站加载速度慢对用户参与度有明显的影响,特别是在电子商务网站上,近一半的用户希望加载在2秒内完成。如果加载时间超过3秒,40%的用户将会退出。页面响应每延迟1秒就意味着7%的用户不再做进一步操作。这不仅意味着流量的损失,而且还会导致收入损失。
此外,网站性能不仅会影响用户,而且还会影响网站在Google搜索结果中的排名。早在2010年,Google就指出:页面加载速度是影响网站搜索结果排名的因素之一。尽管网站内容的相关性始终是影响网站搜索排名的最重要因素,但页面加载速度确实也有一定影响。
让我们来看看“传奇音调”(Legendary Tones)网站的搜索排名。这是一个关于吉他和吉他配件的博客,很受欢迎,每月大约有2万名独立访问者。该网站通过自然搜索结果获取了其大部分流量,并且提供了优质内容。可以使用Google Analytics获得所有页面的平均速度数据,并将其与平均排名关联。图1-1显示了2015年某一个月的结果。
图1-1 “传奇音调”网站上所有页面的平均排名与Google的页面下载时间之间的关系。数值越低,排名越好
由图1-1可知,各个页面的搜索排名基本保持稳定,但是当爬取时间超过1秒时,排名就会下滑。因此,我们需要认真对待性能问题。如果你正在运营一个内容型网站,例如博客,那么自然搜索排名就是你最重要的流量来源。缩短网站的加载时间是网站运营成功的重要因素。
既然知道了性能的重要性,那么我们可以开始讨论Web服务器如何进行通信,以及这个过程是如何使网站变慢的。
1.1.2 Web浏览器如何与Web服务器通信
在理解Web优化的必要性之前,要先知道问题根源所在——浏览器和服务器通信方式的基本属性导致了这个问题,如图1-2所示。
图1-2 用户向example.com发送请求。用户通过浏览器发送网页请求,然后必须等待服务器响应并发送内容。服务器发送响应后,用户才能在浏览器中接收到网页
当人们说“Web性能的重点是网站加载速度更快”时,他们的主要关注点是缩短加载时间。简言之,加载时间就是从用户请求网站到网站出现在用户屏幕上所经历的时间。其驱动机制也就是从用户请求内容到服务器响应到达用户所消耗的时间。
可以将这个过程想象为:你走进一家咖啡店,点了一杯深度烘焙咖啡,然后稍等片刻,你就可以享用到。从根本上看,点咖啡跟与Web服务器通信并没有什么不同:你请求了某些内容,最后得到了它。
当浏览器请求网页时,它使用一种被称为超文本传输协议(通常称为HTTP)的协议和服务器通信。浏览器发出一个 HTTP请求,Web服务器回以一个 HTTP响应,响应中包含了状态码和请求的内容。
在图1-3中,你可以看到向example.com发出的一个请求(这个网站是实际存在的,信不信由你)。动词GET要求服务器定位到/index.html。由于HTTP协议有好几个版本,因此服务器需要知道正在使用哪个版本的协议(在本例中是HTTP/1.1)。最后,请求要指明需要哪个主机名的资源。
图1-3 剖析对example.com的HTTP请求
发出请求后,会收到一个200 OK的响应码,这个响应码确认了请求的资源确实存在,且响应中还包含了index.html的内容。随后,Web浏览器会下载并解析index.html的内容。
上述所有步骤都会产生所谓的延迟:包括等待请求到达Web服务器所花费的时间、Web服务器汇集和发送响应内容所花费的时间,以及Web浏览器下载响应内容的时间。提高性能的主要目的之一就是减少延迟,即减少响应到达客户端所需要的时间。当单个请求(例如示例中的example.com)发生延迟时,产生的影响可能微不足道。但实际上,加载任何一个网站都不仅仅是对单个内容的请求。随着这些请求数量的增加,用户体验越来越容易受到加载速度变慢的影响。
在HTTP/1服务器和浏览器的通信中,可能会出现一种被称为队头阻塞(head-of-line blocking)的现象。之所以会发生这种情况,是因为浏览器限制了单一时间点内发出的请求数(通常是6个)。当一个或者多个请求正在处理,而其余请求已完成时,对内容的新请求将会被阻塞,直到原先剩余的请求完成为止。这种行为会增加页面的加载时间。
HTTP/2是HTTP的一个新版本,它在很大程度上解决了队头阻塞问题,并在浏览器中得到了广泛支持。服务器端的职责是支持协议实现,然而直至2017年6月,大约15%的Web服务器使用了HTTP/2。由于HTTP/2能够使不支持HTTP/2的客户端回退到HTTP/1,因此,仅支持HTTP/1的客户端仍然容易受到旧版本协议的影响。此外,任何与HTTP/1服务器通信的浏览器都会遇到相同的问题,不管其支持HTTP/2的能力如何。
我们所在的这个世界很复杂,所以目前仍需要同时兼容协议的两个版本。接下来,我们会讨论针对HTTP/1优化站点的方法,但你可能会惊讶地发现,其中的一些实践在HTTP/2上是起反作用的。如果想了解有关HTTP/2的更多信息,以及如何在一定条件下实现每个协议版本的最佳工作流,请参见第11章。
下一节将介绍网站如何加载内容,以及这个过程如何导致网站出现性能问题。
1.1.3 Web页面如何加载
在一个单调的世界里,或许所有网站都会像example.com这样:一个网页没有任何图像和JavaScript,样式也非常少。但在现实世界中,网站往往比单个HTML要复杂得多。网站作为视觉媒体的一种,可以为内容提供更多效果:样式表可以将设计运用于平淡的标记,JavaScript可以将静态页面转换成具有复杂行为的应用。听起来似乎不错,但是上述这些特性是有成本的。图1-4展示了用户从Web服务器获取index.html的一个请求。
图1-4 从Web服务器获取index.html的步骤
浏览器在下载index.html后,会发现一个链接到样式表的<link>标签、两个链接到JavaScript文件的<script>标签和一个引用图像的<img>标签。当浏览器发现这些对其他文件的引用时,就会代表用户发起新的HTTP请求,以检索它们。最初的一个网页请求最后变成了5个请求。尽管5个请求并不多,但一个典型网站的请求数通常很容易就能达到其10倍,而一个复杂的网站甚至可以拥有100个左右的请求。随着请求数的增加,需要下载的数据量也会增加。而随着请求及其附带数据的增加,页面加载所需的时间也会增加。
这就是提高网站性能的挑战:在现代网站自身的需求和尽快提供服务之间取得平衡。你需要了解性能提升技术,这样才能防止复杂Web体验影响用户体验中最有价值的部分:访问内容的能力。