右击 -> 查看源文件,和其他一些前端性能测试技巧
本文为原创翻译
原文为
Right Click -> View Source And other tips for performance testing the front end
By R. Scott Barber
右击 -> 查看源文件,和其他一些前端性能测试技巧
最近读了Steve Souders的High Performance Web Sites: Essential Knowledge for Frontend Engineers(O’Reilly, 2007),这本书的副标题是 “14 Steps to Faster-Loading Web Sites”。在你发现此书面向对象为开发人员,从而停止阅读之前,考虑以下几点:
-
作者的研究表明,网页响应时间约80%-90%是由前端设计决定的。而我的经验中,这个数字更应该是50%-80%,但我的经验多来自于那些被重新设计为WEB架构的多用户应用,或者是那些有着严重后端性能问题的应用(请我来定位问题)。
-
和性能测试人员有关的几乎所有的工具、培训、文章和会议,都集中在系统的后端。以至于大部分人认为,系统的前端性能无需担心,因为我们无法控制客户端的系统。
-
根据我的经验,网站的前端设计和开发,几乎不会考虑到性能问题,除了尽量减小图片的大小。我也从未让团队做过客户端页面的HTML代码审查,从未在这些代码上做过单元测试,也从未见过测试人员有意的对HTML进行一些性能测试。
结合上面几点,你将得知,没有人关注页面上的可能存在的性能优化,而这种优化很可能是最容易实现,效果却又最明显的。读了这本书我发现,我经常对大多数的前端性能问题进行测试,但自己却没有意识到。作者提到的一些内容,我可能永远也不会想到去测试,不对这些内容进行更主动的测试是个错误,这些测试的成本是非常低的,无论是在时间上,还是在所需的工具和资源上。实际上,在测试网站的时候,我经常拿出整个性能测试的前15分钟来完成大部分的前端测试,虽然我承认,15分钟只够测试几个页面。
通过这篇文章,我讲解了如何通过手工、负载生成工具、网络协议分析工具、助手网站以及浏览器插件,来进行测试。我已经通过以下免费工具(不是免费试用版,是无任何限制的免费版)完成了这些工作。如果你的公司不允许使用免费软件,我相信只要简单的搜索一下,就可以找到一堆可以替代的工具,这些工具将花费你公司足够多的钱,从而让他们重视。(如果你认为这只是个笑话,很可惜它不是。在咨询过我的团队和接受我培训的个人中,有超过50%的人说过不允许在公司的机器和网络上使用免费、开源、共享、甚至是有时间限制的免费试用版软件。)
- 免费或者开源的负载生成工具
o JMeter (http://jakarta.apache.org/jmeter/)
o WebLoad (http://www.webload.org/)
o OpenSTA (http://www.opensta.org/)
- 免费或者开源的网络协议分析工具
o Ethereal (http://www.ethereal.com/)
o Fiddler (http://www.fiddlertool.com/)
- 免费的浏览器插件
o Firebug (http://www.getfirebug.com/) with YSlow (http://developer.yahoo.com/yslow/) for Firefox
o HttpWatch (http://www.httpwatch.com) for IE
- 免费的助手网站
o Web Page Analyzer - from Website Optimization: Free Website Performance Tool and Web Page Speed Analysis (http://www.websiteoptimization.com/services/analyze/)
o Gomez Instant Site Test (http://www.gomez.com/info_center/instant_test.php)
有了这些,让我们来看一些你只需看完本文能做的测试,这些测试只需在web层面上即可进行,却可能会显著的改善终端用户的响应时间。
HTTP请求数
页面的获取不是在一个事务中完成的。通常HTML文件需要一个请求,样式表需要一个或多个请求,外部脚本需要一个或多个请求,图片、多媒体内容、以及第三方那个内容如广告等需要多个请求。即使很多对象已经存在于浏览器缓存中了,还是需要频繁的向服务器发送请求,以确认缓存中的对象是否“fresh”。这意味着页面上的每一个对象都十分可能会增加负担,进而在用户视角上降低了了性能,即使客户端的浏览器已经缓存了所需的对象。如下几种途径,可以确定页面发送了多少个请求,以及请求的内容。
无论你用哪种方法,你将首先清除掉浏览器的缓存,或者访问页面两次(一次通过ctrl + F5来强制刷新缓存)以确保能够看到所有的请求。因为这些方法只能收集到真实的请求,如果不清除或刷新缓存可能会导致一些遗漏,让你以为没有去请求一些样式表、脚本、图片和多媒体内容,很多配置或条件会对此产生影响,而你可能不知道要去设置这些。
-
如果你使用了负载生成工具或者网络协议分析工具,你可以直接开始录制了,然后浏览感兴趣的页面。在你录制的内容中寻找“GET”语句,看一下请求了什么。记住,有些工具,录制下来的脚本默认只显示基础的HTML请求,不包括子请求(对样式表、图片、脚本等的请求),如果要看到所有的请求需要进一步的设置。
-
如果你的测试环境允许装浏览器插件,那么有好几种方法可以使这个工作变得简单。根据你所用的浏览器,或者希望测的浏览器,我推荐:
a. FireFox:FireBug+YSlow
b. IE: HttpWatch
-
如果你无法使用任何工具,你仍将有几种选择:
a. 访问上面列出的一个助手网站,输入你想测试的页面的URL,点提交。
b. FireFox中,右击页面,选Page Info,导航至Media Tab。注意,这个方法不会显示脚本和样式表,但会显示出请求的图片和其他多媒体内容。
c. IE中,右击页面然后选择View Source。这里,你需要搜寻“link”和“img”字段。如果你找到了样式表的连接(到.css文件的连接),你还需要手动的下载每个样式表,然后在其中搜索“url”字样,因为这些可能会用来请求脚本、图片和多媒体内容。(这是目前为止最笨的方法,但仍能为你提供信息)
有了你的请求列表以后,第一件事要做的就是看看数量——过多的请求会让页面变慢。有如下几个指标来判断是否是过多的请求。
-
外部样式表请求多于一个。确实有一些时候是应该将页面样式拆分成几个样式表,但这情况并不常见,而且对性能显然没有好处。一般来说,只有当有一个主样式表应用到很多页面,第二个大的样式表只应用到几个页面时,保留多于一个样式表才是个好方法。
-
同一域中脚本的请求多于一个。虽然连接多个外部脚本比连接多个样式表有更好的理由,多个外部脚本连接比一个连接性能更好,仍然是不常见的。如果你测试的页面是一个复杂的数据输入表单,那么将表单的验证脚本同其他页面的通用脚本分离可能会有些意义。这样做会减少其他页面(除了表单)的大小,从而改善那些页面的性能,但多出的请求还是会轻微的降低表单页面的性能。不管如何,多于一个外部脚本,至少是值得注意一下的。
-
大量的图片。我没法说“大量的”是多少,但我可以告诉你,IE7和FireFox 2.x默认每主机名可以有2个并行下载(HTTP/1.1,大部分新网站都是)。这意味着,不管你的图片大小是多少,浏览器一次只能下载两个,只有当之前的两个都处理完,才会开始接下来的两个。在HTTP/1.0中是不同的,FireFox默认每主机名可以有8并行下载,IE各版本不同,但肯定不会低于2。这种变化产生的效果就是,使用类似大小但是数量最少的图片易于产生最佳的性能。这和小图片总是好的那种观点是相反的。将几个小图片合成一个或两个大些的图片,通常会改善性能。当然,这就又会出现一个临界点。图片大小和图片的数量是值得前端工程师仔细研究的,测试多种选择以达到最佳性能。有一个广受好评的“rull-of-thumb”(提供类似问题的指导),奉劝当一个页面超过12个请求时,一定要谨慎。Souders的这本书和Andrew B. King的in Speed Up Your Site: Web Site Optimization(New Riders, 2003)中都采用了这个数字,而Aaron Hopkins在网站上发表的文章“Optimizing Page Load Time”让这个数字更有说服力。
HTTP请求的顺序
很多类似的方法都可以用来确定页面上请求的顺序(前面提到的助手网站和FireFox的“Page Info”除外,为了突出数量和大小等问题,将请求按类型或者大小进行了分组和排序)。我们所关注的顺序是:
-
首先请求样式表。在样式表下载完之前,页面是不会显示的。或者是下载完样式表要重新刷新页面。基于这一点,让样式表在HTML页面之后第一批请求是非常重要的。
-
最后请求脚本(至少是要靠后)。当开始请求一个脚本的时候,在脚本完全下载完之前不会再发出对其他对象的请求。此外,脚本下载过程中,浏览器将暂停显示页面内容。这意味着在脚本下载过程中完成的任何对象的下载,都不会被显示出来,从而给人感觉页面的展现停止了。所以一定要把脚本的请求放到用户最感兴趣的对象之后。记住,大多数用户眼中的响应速度是由他们感兴趣的内容决定的,而不是整个页面的载入时间。
不管你是看HTML源文件还是录制请求,你需要关注的就是样式表最先被请求,脚本在最后或者至少是非常靠后时请求。有一个常见的争论,说负责与用户交互的脚本(如图像映射、对象反转)应该早些被请求,这样用户会有更好的体验,即便整个页面还正在下载过程中。但我的经验里,由于下载而产生的页面停止比无法获得图像映射、对象反转功能更容易使用户变得焦躁甚至是离开页面。
重定向和隐藏错误
你仍然可以使用相同的方法来检查重定向问题(3xx状态码),客户错误(4xx),和服务器错误(5xx)。这里,你关注的信息是:
-
过多的3xx。3xx状态表示,请求被处理了,但是浏览器需要到另一个地址去获取所需对象,这就产生了附加的请求和响应。虽然有很多的原因可以使用重定向,检查一下是否有意使用和存在好理由还是值得做的。比如,将一个删除掉的页面重定向到新地址,或者将明显拼错的页面重定向到正确的地址,这就是个好的使用理由。图片的父级目录被移动了,没有人去维护更新链接,这就不是一个需要使用重定向、从而接受一些性能下降的好理由。
-
任何4xx。用户的请求有问题时就会返回4xx状态码。最常见的是404,表示服务器上找不到被请求的对象。一般说来,如果页面的显示和功能都正常,但请求却返回了4xx,那就说明页面请求了不需要的对象,也耗费了多余的时间。
-
任何5xx。5xx表示处理请求时,服务器上发生了错误。任何5xx的状态都需要开发团队注意。
我将这些都称作隐藏错误,是因为当它们发生在非主HTML上时,用户通常是察觉不到的。有时,这些状态码预示着有更深层的错误,但是无论如何,它们都导致了与页面内容无关的请求,这些请求通常也都是完全没有必要的。
HTTP响应头
要检查HTTP响应头,需要使用负载生成工具、网络分析工具或者是浏览器插件。如果你没有这些工具,一个助手网站可以帮到你。我推荐Peter Forret的网站“View and analyze HTTP headers” (http://web.forret.com/tools/analyze.aspx),你只需输入页面的URL,网站就会获取到web服务器返回的一系列HTTP头,这样就可以检查页面过期和缓存等配置了。至于具体哪些是合适的、哪些是不不要的性能损失,这是和很多内容息息相关的,如网页和对象变化的频率、用户访问网站的频率、还有用户看到过时内容的相对风险。但是不管怎样,下面的这些是永远值得检查的:
-
过期时间是否恰当。如果一个对象的HTTP响应中没有过期时间这行,每次用户请求包含这个对象的页面时,都会向服务器发送一个请求,来判断缓存的这个版本是否“新鲜”。如果你有一些不易过期的对象(如公司的Logo),你可以通过设置一个未来很远的日期来避免这种有效性检查。过期时间最多应用在图片上,但在脚本、样式表、AJAX和FLASH等内容上也经常是适用的。检查一下没有过期时间的对象吧,看看是不是有不合适的。
-
ETags是否恰当。ETags是一种web服务器和浏览器使用的认证手段,用来判断客户机器上缓存的对象是否和服务器上的匹配。使用ETags的问题在于,它们对于一个特定的服务器通常是唯一的,这意味着如果网站有多个web服务器,ETags是会出现问题的。如果你确定只有一个web服务器,那么使用ETags是个不错的主意。如果是多个服务器,你就必须查明是否考虑到了这点,或者干脆建议不使用ETags。
- 其他缓存控制。你可能会看到类似的内容,Cache-Control、Last-Modified、Pragma、Set-Cookie、Age。如果你看到了,那么确保这些配置是有意义的。如果没有找到,而你又觉得应该有这些东西,那么找人看一下吧。
说到底,其实本质内容就是你要检查HTTP响应头,来判断网站是否已被合理配置来利用浏览器的缓存。通常,判断这些配置是否恰当的唯一方法,是同管理员和架构师探讨网站是如何使用的、以及是如何设计的,尤其是和浏览器缓存有关的地方。
源文件和其他对象
最后,如果你没以前没做过这些,你需要手工检查HTML源文件、css、脚本、图片以及其他对象。到现在,我还没发现任何一款能够节省我们的时间、对各种情况做出充分检查、并对前端性能提出建议的工具,虽然一些网站使用的HTML、脚本、图片的编辑器还是有一些帮助的。最后,关于前端性能测试,我的建议是:
-
确保脚本和CSS没有写在HTML源文件中。将脚本和CSS直接写在HTML中来提高性能,几乎是不可能的。原因很简单:网页的主HTML是更新最为频繁的部分之一,因此从缓存中受益最少。既然HTML很可能每次都要下载,只有尽量减小大小才是上策。将脚本和CSS与HTML分离,以便利用缓存,是肯定会提高性能的。
-
确保样式和脚本不重复。样式和脚本包含重复内容是非常恶心的。有时,不同的文件中有重复内容,有时在同一个文件中就会重复。你可能不想花费时间去做一个全面检查,那么只需快速的扫描一遍源文件,经常就能发现是否存在明显的重复。
-
检查代码最小化。最小化,指压缩和优化代码,让相关功能使用最少的代码行数。当检查HTML源文件、外部脚本和样式表时,需要注意过多的注释、空格、换行、变量名长度、以及其他能够增加文件大小的内容。
-
检查图片的大小和压缩。虽然大家都明白,仍然还有很多网页设计者使用这样一些图片格式,要么有不必要的文件大小、要么是同显示尺寸不同的尺寸、要么就是超过了所需要的品质。通常,GIF格式的图片是被压缩成64位甚至更少颜色的,它们完全满足大部分的图片和缩略图;JPG格式的图片被压缩成256位或者更少,对于照片来说也完全够用;通过HTML的height/width属性来缩放图片,不如创建再一个新的大小的图片。
这些内容,靠常识判断即可。例如,一些网站将所有的文件、目录以及变量的名字减少到两个甚至更少的字符,将这作为一种减小文件大小的策略。从纯粹的性能角度来看,这是好的;但是,对大多数网站来说,维持这些东西所产生的工作量完全抹杀了它的价值。你需要同团队一起,在去重、最小化、压缩和实用性之间找到一个平衡点。
总结
本文介绍了几种测试,可以用来判断网站是否可能会出现前端性能问题。检查这些可能的性能优化,可能会让用户感受到的响应时间提升50%甚至更多。我确信,一旦你有了自己的工具箱、插件和助手网站,并且实际的练过几次之后,你只需花费比读这篇文章更少的时间,就能检查一个网站是否有这些问题了。有了这么大性能优化的可能性,又在时间和工具上投入这么少,我实在是找不到任何不进行这些测似的理由。