Web 性能核心优化点

Web性能核心优化点

作者/Ilya Grigorik

谷歌“Web加速”(Make The Web Fast)团队的性能工程师、开发大使。他每天的主要工作就是琢磨怎么让Web应用速度更快,总结并推广能够提升应用性能的最佳实践。

在任何复杂的系统中,性能优化的很大一部分工作就是把不同层之间的交互过程分解开来,弄清楚每一层次交互的约束和限制。优化不同层之间的交互与解一组方程没有什么不同,因为不同层之间总是相互依赖,但优化方式却有很多可能性。任何优化建议和最佳做法都不是一成不变的,涉及的每个要素都是动态发展的:浏览器越来越快、用户上网条件不断改善、Web应用的功能和复杂度也与日俱增。

因此,在讨论具体的最佳实践之前,一定要先明确真正的问题在哪里:什么是现代Web应用,我们手里有什么工具,如何测量Web性能,系统的哪些部分对优化有利或有碍?

超文本、网页和Web应用

互联网在过去几十年的发展过程中,至少带给了我们三种体验:超文本文档、富媒体网页和交互式Web应用。不可否认,后两种之间的界限有时候对用户来说很模糊,但从性能的角度看,这几种形式都要求我们在讨论问题、测量和定义性能时采取不同的手段。

  • 超文本文档

    万维网就起源于超文本文档,一种只有基本格式,但支持超链接的纯文本文档。按照现代眼光来看,这种文档或许没什么值得大惊小怪的,但它验证了万维网的假设、前景及巨大的实用价值。

  • 富媒体网页

    HTML工作组和早期的浏览器开发商扩展了超文本,使其支持更多的媒体,如图片和音频,同时也为丰富布局增加了很多手段。网页时代到来了,我们可以基于不同的媒体构建可见的页面布局了。但网页还只是看起来漂亮,很大程度上没有交互功能,与可打印的页面没有区别。

  • Web应用

    JavaScript及后来DHTML和Ajax的加入,再一次革命了Web,把简单的网页转换成了交互式Web应用。Web应用可以在浏览器中直接响应用户操作。于是,Outlook Web Access(IE5中的XMLHTTP就诞生于这个应用)等最早的、成熟的浏览器应用出现,也揭开了脚本、样式表和标记文档之间复杂依赖的新时代。

HTTP 0.9会话由一个文档请求构成,这对于取得超文本内容完全够用了:一个文档、一个TCP连接,然后关闭连接。因此,提升性能就是围绕短期TCP连接优化一次HTTP请求。

富媒体网页的出现改变了这个局面,因为一个简单的文档,变成了文档加依赖资源。因此,HTTP 1.0引入了HTTP元数据的表示法(首部),HTTP 1.1又加入了各种旨在提升性能的机制,如缓存、持久连接,等等。事实上,多TCP连接目前仍然存在,性能的关键指标已经从文档加载时间,变成了页面加载时间,常简写为PLT(Page Load Time)。

最后,Web应用把网页的简单依赖关系(在标签中使用媒体作为基本内容的补充)转换成了复杂的依赖关系:标记定义结构、样式表定义布局,而脚本构建最终的交互式应用,响应用户输入,并在交互期间创建样式表和标记。

结果,页面加载时间,这个一直以来衡量Web性能的事实标准,作为一个性能基础也越来越显得不够了。我们不再是构建网页,而是在构建一个动态、交互的Web应用。除了测量每个资源及整个页面的加载时间(PLT),还要回答有关应用的如下几个问题:

  • 应用加载过程中的里程碑是什么?
  • 用户第一次交互的时机何在?
  • 什么交互应该吸引用户参与?
  • 每个用户的参与及转化率如何?

性能好坏及优化策略成功与否,与你定义应用的特定基准和条件,并反复测试的效果直接相关。没有什么比得上应用特定的知识和测量,在关系到赢利目标和商业指标的情况下更是如此。

剖析现代Web应用

现代Web应用到底长啥样?HTTP Archive(http://httparchive.org/)可以回答这个问题。这个网站项目一直在抓取世界上是热门的网站(Alexa前100万名中的30多万名),记录、聚合并分析每个网站使用的资源、内容类型、首部及其他元数据的数量。

2013年初,一个普通的Web应用由下列内容构成。

  • 90个请求,发送到15个主机,总下载量1311 KB ◦HTML:10个请求,52 KB

    • 图片:55个请求,812 KB
    • JavaScript:15个请求,216 KB
    • CSS:5个请求,36 KB
    • 其他资源:5个请求,195 KB

在你读到这里的时候,前面所有数字都会变大,持续向上的趋势一直都很稳定,而且没有停止的迹象。不过,抛开实际的请求和字节数不提,更值得关注的还是个别组件的量级:现在,一个普通的Web应用大约就有1 MB,有100个左右的资源分散在15台不同的主机上!

与桌面应用相比,Web应用不需要单独安装,只要输入URL,按下回车键,就可以正常运行。可是,桌面应用只需要安装一次,而Web应用每次访问都需要走一遍“安装过程”——下载资源、构建DOM和CSSOM、运行JavaScript。正因为如此,Web性能研究迅速发展,成为人们热议的话题也就不足为怪了。上百个资源、成兆字节的数据、数十个不同的主机,所有这些都必须在短短几百毫秒内亲密接触一次,才能带来即刻呈现的Web体验。

速度、性能与用户期望

速度和性能是两个相对的概念。每个应用都要满足自己特定的需求,因为商业条件、应用场景、用户期望,以及功能复杂性各不相同。尽管如此,如果应用必须对用户作出响应,那我们就必须从用户角度来考虑可感知的处理时间这个常量。事实上,虽然生活节奏越来越快——至少我们感觉如此,但人类的感知和反应时间则一直都没有变过(如下表所示),而且与应用的类型(在线或离线)、媒体的类型(笔记本、台式机或移动设备)无关。

表 时间和用户感觉

{%}

如果想让人感觉很快,就必须在几百毫秒内响应用户操作。超过1 s,用户的预期流程就会中断,心思就会向其他任务转移,而超过10秒钟,除非你有反馈,否则用户基本上就会终止任务!

现在,把DNS查询,随后的TCP握手,以及请求网页所需的几次往返时间都算上,光网络上的延迟就能轻易突破100~1000 ms的预算。难怪有那么多用户,特别是那些移动或无线用户,抱怨上网速度慢了!

资源瀑布

谈到Web性能,必然要谈资源瀑布。事实上,资源瀑布很可能是我们可以用来分析网络性能,诊断网络问题的一个最有价值的工具。很多浏览器都内置了一些手段,让我们能查看资源瀑布。此外,还有一些不错的在线工具,比如WebPageTest(http://www.webpagetest.org/),可以在不同的浏览器中呈现资源瀑布。

首先,必须知道每一个HTTP请求都由很多独立的阶段构成:DNS解析、TCP连接握手、TLS协商(必要时)、发送HTTP请求,然后下载内容。这些阶段的时长在不同的浏览器中会略有不同,但为了简单起见,这里就使用WebPageTest测试的结果。请大家提前熟悉每种颜色在自己浏览器中的含义。

{%}

图 HTTP请求的构成(WebPageTest)

仔细看一下上图,打开Yahoo!主页花了683 ms,而其中有200多毫秒在等待网络就绪,占到了请求延迟的30%!然而,请求文档还只是开始,现代的Web应用还需要各种资源配合来生成最终结果。准确地说,要加载Yahoo!主页,浏览器要请求52个资源,从30个不同的主机获得,这些资源加起来总共486 KB。

{%}

图 Yahoo.com资源瀑布图(WebPageTest,2013年3月)

资源的瀑布图能够揭示出页面的结构和浏览器处理顺序。首先,取得www.yahoo.com对应的文档,同时分派新的HTTP请求:HTTP解析是递增执行的,这样浏览器可以及早发现必要的资源,然后并行发送请求。实际上,何时获得什么资源很大程度上取决于标记结构。浏览器可以变更某些请求的优先顺序,但递增地发现文档中的每一个资源,最终造就了不同资源间的“瀑布效果”。

其次,“Start Render”(绿色的竖线)会在所有资源下载完成前开始,以便用户在页面构建期间就能与之交互。其实,“Document Complete”事件(蓝色的竖线)也会在剩余资源下载完成前触发。换句话说,浏览器的加载旋转图标此时停止旋转,用户可以继续与页面交互,但Yahoo!主页会渐进地在后台填充后续内容,比如广告和社交部件。

最早渲染时间、文档完成时间和最后资源获取时间,这三个时间说明我们讨论Web性能时有三个不同测量指标。我们应该关注哪一个时间呢?答案并不唯一,因应用而不同!Yahoo!的工程师们选择了利用浏览器递增加载机制,让用户能够尽早与重要内容交互。而这样一来,他们必须根据应用不同,确定哪些内容重要(须先加载),哪些内容不重要(可以后填充)。

网络的瀑布图是个很强大的工具,有助于揭示任何页面或应用是否处于优化状态。前面分析和优化资源瀑布的过程,一般称为前端性能分析和优化。不过,这个称呼有误导性,好像所有性能瓶颈都在客户端似的。实际上,尽管JavaScript、CSS和渲染流水线很重要,而且资源对性能影响很大,但服务器响应时间和网络延迟(“后端性能”)对资源瀑布的影响也不容忽视。毕竟,如果网络被阻塞,也就谈不上什么解析或运行资源了!

为了说明这一点,只要切换到WebPageTest资源瀑布的连接视图即可。

{%}

图 Yahoo.com资源瀑布图的连接视图(WebPageTest,2013年3月)

资源瀑布图记录的是HTTP请求,而连接视图展示了每个TCP连接(这里共30个)的生命期,这些连接用于获取Yahoo!主页的资源。哪里比较突出呢?注意蓝色的下载时间,很短,在每个连接的总延迟里几乎微不足道。这里总共发生了15次DNS查询,30次TCP握手,还有很多等待接收每个响应第一个字节的网络延迟(绿色)。

为什么有些请求只显示绿色条(第一字节接收时间)?因为很多响应很小,相应的下载时间没有在图中体现。事实上,请求、响应的主要时间通常是往返延迟和服务器处理时间。

最后,也是最重要的,连接视图的底部显示了带宽利用率曲线。除了少量数据爆发外,可用连接的带宽利用率很低。这说明性能的限制并不在带宽!难道这是个异常现象,或者浏览器问题?都不是。对大多数应用而言,带宽的的确确不是性能的限制因素。限制Web性能的主要因素是客户端与服务器之间的网络往返延迟。

性能来源:计算、渲染和网络访问

Web应用的执行主要涉及三个任务:取得资源、页面布局和渲染、JavaScript执行。其中,渲染和脚本执行在一个线程上交错进行,不可能并发修改生成的DOM。实际上,优化运行时的渲染和脚本执行是至关重要的。

可是,就算优化了JavaScript执行和渲染管道,如果浏览器因网络阻塞而等待资源到来,那结果也好不到哪里去。对运行在浏览器中的应用来说,迅速而有效地获取网络资源是第一要义。

有人可能会问,互联网今天的速度不是快多了吗,难道网络还会阻塞?是的,我们的应用也比以前大多了。然而,假如真像每个ISP和移动运营商鼓吹的那样,全球平均网速已经达到3.1 Mbit/s,而且还在继续提速,Web应用大一点又算得了什么呢?可惜的是,凭直觉以及前面展示的Yahoo!的例子,我们知道如果真是这样,那你就不用接着看这篇文章了。好,下面我们仔细谈一谈。

更多带宽其实不(太)重要

先别急,带宽当然重要!毕竟,所有ISP和移动运营商的广告,都意在提醒我们高带宽的好处:上传和下载加速、更流畅地欣赏视频,都有赖于[请读者在此插入最新数字]Mbit/s的速度!

能接入更高带宽固然好,特别是传输大块数据时更是如此,比如在线听音乐、看视频,或者下载大文件。可是,日常上网浏览需要的是从数十台主机获取较小的资源,这时候往返时间就成了瓶颈:

  • 在Yahoo!主页上看视频受限于带宽;
  • 加载和渲染Yahoo!主页受限于延迟。

根据在线视频品质及编码不同,需要的带宽从几百Kbit/s到几Mbit/s不等。比如,要流畅观看1080P的高清视频,需要3 Mbit/s以上的带宽。这个带宽是很多用户触手可及的,Netflix等在线视频网站的流行也印证了这一点。那么,为什么下载比视频小得多得多Web应用,在能流畅观看高清视频的连接上却成了难题呢?

延迟是性能瓶颈

关于为什么延迟会成为浏览网页的限制因素,我们就来通过两张图(如下所示),定量地感受一下不同的带宽和延迟时间对页面加载时间分别有什么影响。这两张图来自SPDY协议的开发者之一Mike Belshe,测试的是互联网上最热门的一些站点。

{%}

图 页面加载时间与带宽和延迟的关系

在第一个测试中,连接的延迟时间固定而带宽递增,从1 Mbit/s依次递增至10 Mbit/s。注意一开始,从1 Mbit/s升级到2 Mbit/s,页面加载时间几乎减少了一半,这也是我们希望看到的结果。可是,在此之后,带宽递增,加载时间减少得越来越不明显。而当带宽超过5 Mbit/s时,加载时间的减少比例只有几个百分点,从5 Mbit/s升级到10 Mbit/s,页面加载时间仅降低了5%!

Akamai公司的宽带速度报告显示,美国普通消费者上网带宽已经达到5 Mbit/s以上。很多其他国家很快也能达到这个数字,甚至有的已经超过了它。由此可知,靠提高带宽不会给美国人浏览网页带来多大的性能提升。或许美国人下载大文件、看视频的速度很快,但加载包含这些文件的页面的时间不会明显缩短。换句话说,增加带宽没有那么重要。

然而,在延迟以20 ms递减的试验中,页面加载时间呈线性减少趋势。在选择ISP时,是不是应该把延迟时间而不是带宽放在首位呢?

要让互联网从整体上提速,就必须寻求降低RTT的方法。把跨大西洋的RTT从150 ms降低到100 ms,结果会怎么样?结果比把用户带宽从3.9 Mbit/s提高到10 Mbit/s甚至1 Gbit/s对速度的影响都大。

减少页面加载时间的另一种方法,就是减少加载每个页面过程中的往返次数。今天,加载每个页面都需要客户端到服务器之间的数次往返。这些往返很大程度上是由客户端与服务器之间为建立连接(DNS、TCP、HTTP等)而进行握手所导致的,当然有的是由通信协议引发的(如TCP慢启动)。假如我们能够对协议加以改进,使得加载同样多的数据只需更少的往返,那应该也能够减少页面加载时间。这就是SPDY的目标之一。

——Mike Belshe,更多带宽其实不(太)重要

很多人可能都会惊讶于这两项试验的结果,而实际情况的确如此,这正是TCP握手机制、流量和拥塞控制、由丢包导致的队首拥塞等底层协议特点影响性能的直接后果。大多数HTTP数据流都是小型突发性数据流,而TCP则是为持久连接和大块数据传输而进行过优化的。网络往返时间在大多数情况下都是TCP吞吐量和性能的限制因素。于是,延迟自然也就成了HTTP及大多数基于HTTP交付的应用的性能瓶颈。

如果延迟对大多数有线连接是限制性能的因素,那可想而知,它对无线客户端将是更重要的性能瓶颈。事实上,无线延迟明显更高,因此网络优化是提升移动Web应用性能的关键。

 

{%}

《Web性能权威指南》深入浅出地讲解并演示了针对TCP、UDP和TLS协议的性能优化最佳实践,以及面向无线和移动网络进行优化时的特殊要求。它还全面剖析了浏览器技术的几项重大革新,包括使用这些新技术时在性能方面需要的独到考量。革命性的HTTP 2.0、XHR客户端网络脚本、基于SSE及WebSocket的实时数据流,以及通过WebRTC实现P2P通信,对这些面向未来的重大浏览器技术,本书都从性能优化的角度给出了详尽的解读和分析。