移动网站性能优化:网页加载(转)
原文链接:http://caibaojian.com/mobile-optimization.html
由于移动设备存在的环境限制,如低带宽,高延迟,小内存,低处理器性能的等,迫使开发者不得不想办法通过优化前端页面的性能来满足用户的性能预期。在强调如何解决移动端性能问题上,这篇文章总结了一些前端优化的案例,并且概括了一些加速页面的方法和策略。·
为什么性能会影响这么多
不论你的页面设计地多么有趣、漂亮、交互性好,不管是在桌面还是移动设备上,如果页面需要花2到3秒时间去渲染展示,那么用户都会很快变得不耐烦的。可以预期的是,在页面还在加载的时候,用户很有可能从浏览购买的行为转变为点击回退键或者是关闭浏览器的行为。
不到1秒钟的延迟甚至也会显著地影响收入。在2006年,当时还在Google工作的Marissa Mayer说,由于用户表示希望在一个搜索页上看到多于10个搜索结果,Google就实验性地修改为30个。但是让人吃惊的是,在这个实验里,流量和投资都减少了20个百分点,显然是由于更多的搜索结果导致多花费了半秒时间来加载页面。^5
用户的期望总是在不断的提升。2009年,Forrester研究所的Akamai的一项研究发现表明,网页响应时间可容忍的阀值是2秒,一旦网页相应时间超过3秒,会有40%的用户放弃浏览页面。一年之后,Akamai的另一项研究表明,超过3秒放弃浏览页面的用户比例上升到了57%。^1,7
此外,移动端的用户希望移动设备上的页面性能不亚于桌面PC。由Tealeaf科技(现在已经并入IBM)委托的“Harris的互动2011移动交互调查”显示,在前一年有过移动消费经历的成年人中,有85%希望移动设备上的体验能与手提电脑或者PC上的体验相当,甚至于更好。并且有63%的人表示,一旦他在移动设备上的交易遇到了一个问题,他们就不会再想通过其他渠道去购买这个公司的其他产品了。^10换句话说,差劲的移动页面性能会影响到公司其他各种平台的销售,这其中当然也包括线下的实体店。
移动流量正在迅速增长。对许多消费者而言,他们的手机或者平板设备已经成为他们浏览网络的主要入口了,但是其性能表现却差强人意。2011年2月,Compuware公司委托Equation 研究所做的一项研究表明,几乎一半的移动用户(46%)表示他们手机上的网站加载速度过慢。60%的用户希望页面能在3秒或者更少的时间内加载完成,74%的用户表示,当单个页面加载时间花费5秒或者更多的时候,他们会选择离开这个页面。在2012年,由Strangeloop网络(现已并入Redware)发起的一项针对200家领先的电子商务网站研究表明,3G网络环境下,平均加载时间为11.8秒(图1),而在LTE(4G)环境下,加载时间只有轻微的改善,为8.5秒。^8
移动设备表现性能的三种影响因素
正如上文所说的,移动设备天生有下面三种性能限制:带宽低,内存小,处理器性能低。这些性能挑战又加上一些其他的问题,例如:
网页比以前更大。根据HTTP Archive网站的分析,现在平均的一个web页面需要加载超过1MB的数据,其中包含有图片,Javascript,CSS(Cascading Style Sheets)等。更大的网页会影响桌面PC的显示性能。对于移动端的性能 — 特别是3G环境下的性能 — 影响更严重。这个影响会在今后的三年更加明显。以现在的页面增长速度来说,到2015年,平均的页面大小会达到2MB。
延迟相差巨大。对LTE来说,延迟大概有34ms,对3G来说,延迟大概有350毫秒甚至更多。移动端的延迟性唯一不变的就是延迟时间永远是不定的,即使是在同一个地点,每次的延迟都是不定的。这是由于大量的数据是通过信息塔进行传输的。因此诸如天气,甚至是持有者所面向的方向都有可能成为影响因素。
下载速度相差巨大。下载速度的范围从3G环境下的1Mbps到LTE环境下的31Mbps。把这个和美国平均的带宽15Mbps相比是一个很有意思的事情,3G环境比平均带宽慢了15倍,而LTE却能达到平均带宽的2倍那么快。
M.SITES并不能完全解决移动端性能的问题。
许多网站建设者尝试针对多用户访问,大网页和低流量连接的访问页面,开发出短小,快速,精简的m.sites;但是,这些尝试并没有什么用,当用户有选择权的时候,高达35%的移动用户会选择浏览完整的网站。
这些选择浏览完整网站的用户显然比浏览m.sites的用户更有购买欲望。一个研究表明,移动端每$7.00的消费中,有$5.50是来自于网站的网站浏览,只有$1.00是来自于m.sites,剩下的$0.50则是来自于客户端。^9
解决问题
改善网站性能的主要策略并没有因为从PC变成手机或者平板设备而有变化,只是会参杂一些小的策略。
不论在PC还是在移动浏览器上,页面展示需要的时间里,只有20%是用来读取页面的HTML的。剩下的80%是用来加载额外的像样式表、脚本文件、或者图片这样的资源和执行客户端的程序。
三个主要的改善性能的策略是:
- 减少每个页面需要获取额外资源的HTTP请求数
- 减少每个请求加载的大小
- 优化客户端执行的优先级和脚本执行的效率
由于移动网络通常比桌面机器的网络慢,所以减少请求数和请求加载量是非常重要的。由于移动端的浏览器解析HTML和执行JavaScript的效率比桌面PC低,所以优化客户端程序也是非常关键的。另外,移动端浏览器的缓存大小比桌面PC低,所以需要有方法能重复利用本地的缓存资源。
文章剩余部分总结了能解决这些问题的方法。虽然这些方法大都可以自动化解决,当然也可以由有经验的前端工程师来手动解决。关键就是要知道人工解决这些技术的方法如何控制资源的请求。通常在CMS(内容管理系统)或者其他Web应用中,有些页面包含一些自动生成好的或者离线的HTML片段、CSS或者Javascript文件,这样的页面开发者就不需要去优化它们了。
减少请求
最大的性能漏洞就是一个页面需要发起几十个网络请求来获取诸如样式表、脚本或者图片这样的资源。这个在相对低带宽和高延迟的移动设备连接上来说影响更严重。CDNs(内容分发网络)把资源放在离用户地理位置更近的地方对解决这个问题能起到很大作用,但是比起获取请求,大量的请求对页面加载时间的影响更为严重。而且最近的发现表明,CDNs对移动端用户的性能影响越来越低。
下面的章节讨论了简化HTTP请求的几种方法。
整合资源
对开发者来说,将Javascript代码和CSS样式放到公共的文件中供多个页面共享是一种标准的优化方法。这个方法能很简单的维护代码,并且提高客户端缓存的使用效率。
在Javascript文件中,要确保在一个页面中相同的脚本不会被加载多次。当大团队或者多个团队合作开发的时候,这种冗余的脚本就很容易出现。你可能会对它的发生频率并不低感到非常吃惊。
Sprites是css中处理图片的一项技术。Sprites就是将多张图片整合到一个线性的网状的大图片中。页面就可以将这个大图片一次性获取回来并且做为css的背景图,然后使用css的背景定位属性展示页面需要的图片部分。这种技术将多个请求整合成一个,能显著地改善性能。
实现小贴士:平稳地改进但是需要对资源有控制权限。根据开发者的网站不同权限,一些资源并不需要被整合起来(例如,一些由CMS生成的资源)。还有,对于一些外部域引用的资源,强行整合可能会导致问题。需要注意的是,整合资源对手机浏览器来说是一把双刃剑。整合资源确实会在首次访问减少请求,但是大的资源文件可能会导致缓存失效,所以,需要小心地使用各种技术整合资源,以达到优化本地存储的目的。
使用浏览器缓存和本地缓存
现在所有的浏览器都会使用本地资源去缓存住那些被Cache-Control或者Expires头标记的资源,这些头能标记资源需要缓存的时间。另外,ETag(实体标签)和Last-Modified头来标识当资源过期后是否需要重新请求。浏览器为了减少不必要的服务器请求,尽可能地从本地缓存中获取资源,并且将那些已经过期的、或者当缓存空间减小的时候将那些很久不用的资源进行清理。浏览器缓存通常包括图片,CSS,Javascript代码,这些缓存能合理地提高网站的性能。(比如为了支持后退和前进的按钮,使用一个单独的缓存来保存整个渲染的页面)。
移动浏览器缓存,通常是比桌面PC小的多,这就导致了缓存的数据会很经常被清理。HTML5的缓存基于浏览器缓存提供了一个很好的替换方案。Javascript的localStorage已经在所有主流的桌面和移动端浏览器上都实现了。使用脚本代码能简便地支持HTML5的localStorage操作,可以读写键值数据,每个域名大概有5MB的容量。虽然不同的移动浏览器上读写速度相差很大,但是localStorage大容量的缓存使得它很适合作为客户端的缓存。从localStorage获取资源明显快于从服务器上获取资源,而且在大多数移动设备上也比依靠缓存头或者浏览器的本地缓存更灵活可靠。这是移动浏览器比桌面PC更有优势的一个地方,在桌面PC上,本地缓存仍然优先使用标准的浏览器缓存,导致桌面PC本地缓存的性能落后于移动浏览器。
实现小贴士:需要进一步考虑。虽然localStorage的机制易于实现,但是它的一些控制机制却是非常复杂的。你需要考虑到缓存带给你的所有问题,比如缓存失效(什么时候需要删除缓存?),缓存丢失(当你希望数据在缓存中的时候它并不在怎么办?),还有当缓存满的时候你怎么办?
首次使用的时候在HTML中嵌入资源
HTML的标准是使用链接来加载外部资源。这使得更容易在服务器上(或者在CDN上)操作更新这些资源,而不是在每个页面上修改更新这些资源。根据上文讨论的,这种模式也使得浏览器能从本地缓存而不是服务器上获取资源。
但是对还没有缓存到浏览器localStorage的资源来说,这种模式对网站的性能有负面的影响。一般来说,一个页面需要几十个单独的请求来获取资源从而渲染页面。所以说,从性能的角度来说,如果一个资源没有很高的被缓存的几率的话,最好把它嵌入到页面的HTML中(叫inlining),而不是使用链接外部。脚本和样式是支持内嵌到HTML中的,但是图片和其他的二进制资源其实也是可以通过内嵌包含base64编码的文本来嵌入到HTML中的。
内嵌的缺点是页面的大小会变得非常大,所以对于Web应用来说,关键的是能够跟踪分析这个资源什么时候需要从服务端获取,什么时候已经缓存到客户端了。另外,在第一次请求资源后必须能够使用代码在客户端缓存资源,因此,在移动设备上,使用HTML5 localStorage能很好地做到内嵌。
实现小贴士:平稳处理。由于不知道用户是否已经访问过这个页面了,所以需要网站有机制能生成不同版本的页面。
使用HTML5服务端发送事件
Web应用已经使用了各种从服务器上轮询资源的方法来持续地更新页面。HTML5的EventSource对象和Server-Sent事件能通过浏览器端的JavaScript代码打开一个服务端连接客户端的单向通道。服务端可以使用这个写通道来发送数据,这样能节省了HTTP创建多个轮询请求的消耗。这种方式比HTML的WebSocket更高效。WebSocket的使用场景是,当有许多客户端和服务端的交互的时候(比如消息或者游戏),在全双工连接上建立一个双向通道。
实现小贴士:需要进一步考虑。这个技术是基于具体的技术实现的。如果你的网站当前是使用其他的ajax或者Comet技术来轮询的,转变成Server-Sent 事件需要重构网站的Javascript代码。
消除重定向
当用户在一个移动设备上访问桌面PC网站的时候,Web网站应用通常读取HTTP的user-agent头来判断这个用户是否是来自移动设备的。然后应用会发送带有空HTTP body和重定向HTTP地址头的HTTP 301(或者302)请求,把用户重定向到网站的移动版本上去。但是,这个额外的客户端和服务端的交互通常在移动网络上会消耗几百毫秒。因此,在原先的请求上传递移动的web页会比传递一个重定向的信息并让客户端再请求移动页面更快。
对于那些想要在移动设备上看桌面PC网站的用户来说,你可以在移动web页面上提供一个链接入口,这样也能同时表示你的网站是并不提倡这种行为的。
实现小贴士:虽然这个技术在理论上是简单的,但是实际上并不易于实施。由于有些m.sites是宿主在其他地方的,所以许多网站会选择重定向到一个不同的服务器上。有的网站则是会在重定向请求的时候种植上Cookie告诉Web应用这个用户是在使用移动设备。这种方法可能对web应用来说更容易控制。
减少资源负载
大小问题。渲染小页面更快,获取小资源也更快。减小每个请求的大小通常不如减少页面请求个数那么显著地提高性能。但是,有些技术在性能方面,特别是在需要对带宽和处理器性能精打细算的移动设备环境下,仍然是能带来很大利益的。
压缩文本和图像
诸如gzip这样的压缩技术,依靠增加服务端压缩和浏览器解压的步骤,来减少资源的负载。但是,一般来说,这些操作都是被高度优化过了。而且测试表明,压缩对网站还是起到优化性能的作用的。那些基于文本的响应,包括HTML,XML,JSON(Javascript Object Notation),Javascript,和CSS可以减少大约70%的大小。
浏览器在Accept-Encoding请求头中申明它的解压缩技术,并且当它们接收到服务端返回的Content-Encoding响应头标示的时候,就会按照这个响应头自动做解压操作。
实现小贴士:易于实现。如果设置正确的话,现在所有的Web服务器都支持压缩响应。但是,也有一些桌面PC的安全工具会将请求头中的Accept-Encoding头去掉,这样即使浏览器支持解压缩,用户也无法获取到压缩后的响应。
代码简化
简化通常是使用在脚本和样式文件中,删除一些不必要的字符,比如空格,换行符,或者注释等。不需要暴露给外部的命名就可以被缩短为一个或者两个字符,比如变量名。合适的简化资源通常在客户端不需要做任何其他的处理,并且平均减少20%的资源大小。内嵌在HTML中的脚本和样式文件也是可以精简的。有很多很好的库来做精简化的操作,这些库一般也同时会提供合并多个文件这样减少请求数的服务。
简化带来的好处并不局限于减少带宽和延迟,对于那些移动设备上缓存无法保存的过大资源来说,也是很有改善的。Gzip在这个方面并没有任何帮助,因为资源是在被解压后才被缓存起来的。
实现小贴士:易于实现。Google的Closure Compiler已经难以置信地完成了理解和简化Javascript的工作。但是CSS的简化则没有那么容易,因为对不同浏览器来说有不同的CSS技术能迷惑CSS简化工具,然后让CSS简化后无法正常工作。必须要注意的是,已经有这样的案例了,即使只是删除了不必要的字符,简化工作也有可能破坏页面。所以当你应用简化技术之后,请做一下完整的功能测试工作。
调整图片大小
图片通常是占用了Web页面加载的大部分网络资源,也占用了页面缓存的主要空间。小屏幕的移动设备提供了通过调整图片大小来加速传输和渲染图片资源的机会。如果用户只是在小的移动浏览器窗口中看图片的话,高分辨率的图片就会浪费带宽、处理时间和缓存空间。
为了加速页面渲染速度和减少带宽及内存消耗,可以动态地调整图片大小或者将图片替换为移动设备专用的更小的版本。不要依靠浏览器来将高分辨率的图片转换成小尺寸的图片,这样会浪费带宽。
另外一个方法是先尽快加载一个低分辨率的图片来渲染页面,在onload或者用户已经开始和页面交互以后将这些低分辨率的图片替换成为高分辨率的图片。
实现小贴士:特别应用在高度动态化的网站是有优势的。
使用HTML5和CSS 3.0来简化页面
HTML5包括了一些新的结构元素,例如header,nav,article和footer。使用这些语义化的元素比传统的使用div和span标签能使得页面更简单和更容易解析。一个简单的页面更小加载更快,并且简单的DOM(Document Object Model)代表着更快的JavaScript执行效率。新的标签能很快地应用在包括移动端的新浏览器版本上,并且HTML5设计让那些不支持它的浏览器能平稳过渡使用新标签。
HTML5的一些表单元素提供了许多新属性来完成原本需要javascript来完成的功能。例如,新的placeholder属性用于显示在用户输入进入输入框之前显示的介绍性文字,autofocus属性用于标示哪个输入框应当被自动定位。
也有一些新的输入框元素能不用依靠Javascript就可以完成一些通用的需求。这些新的输入框类型包括像e-mail,URL,数字,范围,日期和时间这样需要复杂的用户交互和输入验证的元素。在移动浏览器上,当需要输入文本的时候,弹出的键盘通常是由特定的输入框类型来做选择的。不支持指定的输入类型的浏览器就会只显示一个文本框。
另外,只要浏览器支持内建的层次,圆角,阴影,动画,过渡和其他的图片效果,CSS 3.0就能帮助你创建轻便简易的页面了,而这些图片效果原先是需要加载图片才能完成的。这样,这些新特性就能加速页面渲染了。
有很多Web站点都提供哪些移动或者桌面浏览器支持哪项性能的更新说明。(例如:http://caniuse.com/ 和 mobilehtml5.org)。
实现小贴士:需要进一步考虑。人工地做这些改动是非常复杂和耗时的。如果你使用CMS,它可以帮你生成许多你不需要控制的HTML和CSS。
优化客户端的程序处理
浏览器按照什么顺序来执行代码生成一个页面,和页面复杂性及JavaScript的技术选择,都对性能有很大的影响。特别在客户端相对较慢的CPUs和少内存的移动端中尤为明显。下面的章节提供一些策略来提升页面处理的性能。
延迟渲染”BELOW-THE-FOLD”内容
可以确定的是如果我们将不可见区域的内容延迟加载,那么页面就会更快地展现在用户面前,这个区域叫做”below the fold”。为了减少页面加载后需要重新访问的内容,可以将图片替换为正确的高宽所标记的<img>标签。
实现小贴士:平稳处理。一些好的Javascript库可以用来处理这些below-the-fold 延迟加载的图像。^12
延迟读取和执行的脚本
在一些移动设备上,解析Javascript代码的速度能达到100毫秒每千字节。许多脚本的库直到页面被渲染以后都是不需要的加载的。下载和解析这些脚本可以很安全地被推迟到onload事件之后来做。例如,一些需要用户交互的行为,比如托和拽,都不大可能在用户看到页面之前被调用。相同的逻辑也可以应用在脚本执行上面。尽量将脚本的执行延迟到onload事件之后,而不是在初始化页面中重要的可被用户看到的内容的时候执行。
这些延迟的脚本可能是你自己写的,更重要的是,也有可能是第三方的。对广告、社交媒体部件、或者分析的差劲的脚本优化会导致阻塞页面的渲染,会增加珍贵的加载时间。当然,你需要小心地评估诸如jquery这样为移动网站设计的大型脚本框架,特别当你仅仅只是使用这些框架中的一些对象的时候更要小心评估。
实现小贴士:平稳处理。许多第三方的框架现在提供延迟加载的异步版本的API。开发者只需要将原先的逻辑转化到这个异步版本。一些JavaScript要做延迟加载会有些复杂,因为在onload之后执行这些脚本需要注意很多注意事项。(例如,你有个脚本需要绑定到onload事件上,你需要做什么?如果你将脚本延迟到onload事件之后,就一定就会失去很多执行的时机。)
使用Ajax来增强进程
Ajax(Asynchronous JavaScript and XML)是一项使用XHR(XMLHttpRequest)对象来从Web服务器上获取数据的技术,它并不需要更新正在运行的页面。Ajax能更新页面上的某个部分而不需要重新构建整个页面。它通常用来提交用户的交互相应,但是也可以用来先加载页面的框架部分,然后当用户准备好浏览网页的时候再填充详细的内容。
尽管是这个名字,但是XMLHttpRequest并不强制要求你只能使用XML。你可以通过调用overrideMineType方法来制定”application/json”类型来使用json替换XML。使用JSON.parse会比使用原生的eval()函数快了几乎两倍,并且更为安全。
同时,切记Ajax的返回响应也会得益于那些应用在普通的返回响应的优化技术上面。确保对你的Ajax返回响应使用了缓存头,简化,gzip压缩,资源合并等技术。
实现小贴士:由于这个技术是根据具体应用不同而不同的,所以很难量化。或许由于跨域问题,你需要使用XHR2,这个技术能使用外部域的资源,从而能进行跨域的XHR请求。
根据网络状况进行适配处理
由于使用更多带宽会使用更多移动网络的费用,所以只有能检测网络的类型才能使用针对特定网络的优化技术。例如,预加载未来使用到的请求是非常聪明的做法,但是如果用户的带宽很稀有,并且加载的有些资源是永远不会用到的话,这个技术就是不合理的了。
在Android 2.2+,navigator.connection.type属性的返回值能让你区分Wifi和2G/3G/4G网络。在Blackberry上,blackberry.network也能提供相似的信息。另外,服务端通过检测请求中的User-Agent头或者其他的嵌入到请求中的信息能让你的应用检测到网络状况。
实现小贴士:需要进一步考虑。检测网络信息的API最近已经有所变化了。^11 接口现在不是直接定义Wi-Fi,3G等网络状况,而是给出了带宽信息和诸如“非常慢,慢,快和非常快”这样的建议。有个属性能给出估计的MB/s值和一个“meterd”的Boolean值来表示它的可信度,但是对浏览器来说,很难根据这个来判断环境。判断当前网络环境然后适配仍然是一种最好的方法,但是这种方法正在被考虑被替换。
对多线程来说尽量使用HTML5的WEB WORKER特性
HTML5中的Web Worker是使用多个线程并发执行Javascript程序。另外,这种特别的多线程实现能减少困惑开发者多年的,在其他平台上遇到的问题。例如,当一个线程需要改变一个正在被其他线程使用的资源该如何处理。在Web Worker中,子线程不能修改主用户界面(UI)线程使用的资源。
对提高移动站点的性能来说,Web Worker中的代码很适合用来预处理用户完成进一步操作所需要的资源的,特别是在用户的带宽资源不紧缺的情况下。在低处理器性能的移动设备上,过多的预加载可能会干扰当前页面的UI响应。使用多线程代码,让Web Worker对象(并且尽可能使用localStorage来缓存数据)在另外一个线程中操作预加载资源,这样就能不影响当前的UI表现了。
要特别说明的是,Web Worker只在Android 2.0以上的版本实现,而且iphone上的ios5之前的版本也不支持。在桌面PC上,总是落后的IE只在IE 10才支持Web Worker。
实现小贴士:平稳过渡。虽然这项技术并不是非常难实现,但是对Web Workers来说,有一些限制需要强制遵守。Web Workers不能进入到页面的DOM,也不能改变页面上的任何东西。Web Worker很适合那种需要后台计算和处理的工作。
将CLICK事件替换成TOUCH事件
在触摸屏设备上,当一个用户触碰屏幕的时候,onclick事件并没有立即触发。设备会使用大约半秒(大多数设备差不多都是300毫秒)来让用户确定是手势操作还是点击操作。这个延迟会很明显地影响用户期望的响应性能。要使用touchend事件来替换才能解决。当用户触碰屏幕的时候,这个事件会立即触发。
为了要确保不会产生用户不期望的行为,你应该也要使用touchstart和touchmove事件。例如,除非同时有个touchstart事件在button上,否则不要判断touchend事件在button上就意味着点击行为 — 因为用户有可能从其他地方触碰开始,然后拖拽到button上触碰结束的。你也可以在touchstart事件之后使用touchmove事件来避免将touchend事件误判为点击,当然前提是需要假设拖拽的手势并不是预期产生点击行为。
另外,你也需要去处理onclick事件来让浏览器改变button的外观从而标识为已点击的状态,同时你也需要处理那些不支持touch事件的浏览器。为了避免代码在touchend和onclick代码中重复执行,你需要在确保用户触碰事件已经在touchend执行了之后,在click事件中调用preventDefault和stopPropagation方法。^4
实现小贴士:需要进一步考虑。这种技术需要更多工作才能在一个页面中增加和维护链接。touch事件的代码必须考虑其他手势,因为替换click的还有可能是缩放或者敲击动作。
支持SPDY协议
应用层HTTP和HTTPS协议导致的一些性能瓶颈,使得不论是桌面还是移动端的网站都非常难受。在2009年,谷歌开始研发一种叫做SPDY(谐意是”speedy”)的协议来替换已有的协议,这种协议宣称能突破这些限制。这个协议的目标是让多种浏览器和多种Web服务都能支持,所以这个协议是开源的,但是初步地,只有Google的Chrome浏览器(在版本10及之后的)和google的站点支持。一旦一个Web服务支持SPDY,那么它上面的所有站点都可以和支持这个协议的浏览器使用SPDY进行交互。将SPDY应用在25个top100的Internet网站上,Google收集到的数据是网站的速度会改善27%到60%不等。^2
SPDY自动使用gzip压缩所有内容,和HTTP不同的是,它连header的数据也使用gzip压缩。SPDY使用多线程技术让多个请求流或者响应流能共用一个TCP连接。另外SPDY允许请求设置优先级,比如,页面中心的视频会比边框的广告拥有更高的优先级。
或许SPDY中最变革性的发明就是流是双向的,并且可以由客户端或者服务端发起,这样能使得信息能推送到客户端,而不用由客户端发起第一次请求。例如,当一个用户第一次浏览一个站点,还没有任何站点的缓存,这个时候服务端就可以在响应中推送所有的请求资源,而不用等候每个资源被再次独立请求了。作为替换协议,服务端可以发送暗示给客户端,提示页面需要哪些资源,同时也允许由客户端来初始化请求。即使是使用后一种这样的方式也比让客户端解析页面然后自己发现有哪些资源需要被请求来得快。
虽然SPDY并没有对移动端有什么特别的设置,但是移动端有限的带宽就使得如果支持SPDY的话,SPDY在减少移动网站的延迟是非常有用的。
来源:前端开发博客