Web性能实践日志

978-7-115-34790-9
作者: 【加拿大】Stoyan Stefanov
译者: 王玉林吴英杰庄婷婷唐云飞
编辑: 陈冀康

图书目录:

详情

本书集合了当今顶尖的Web性能专家的一些实用技巧和技术。任何想要有优化用户体验和Web性能的开发者,都可以阅读本书。这本书收录了大量已发表的 web 性能相关的文章。其中包括了许多性能相关的主题,如开源工具、缓存、移动网络和应用、自动化、用户体验优化、HTML5、JavaScript、CSS3、指标、ROI和网络协议。

图书摘要

版权信息

书名:Web性能实践日志

ISBN:978-7-115-34790-9

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [加] Stoyan Stefanov

  译    王玉林  吴英杰  庄婷婷   唐云飞

  责任编辑  陈冀康

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410

  反盗版热线:(010)81055315

Copyright© 2012 by O’Reilly Media, Inc.

Simplified Chinese Edition, jointly published by O’Reilly Media, Inc. and Posts & Telecom Press, 2014. Authorized translation of the English edition, 2013 O’Reilly Media, Inc., the owner of all rights to publish and sell the same.

All rights reserved including the rights of reproduction in whole or in part in any form.

本书中文简体版由O’Reilly Media, Inc.授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


本书包含了众多领域专家的关于 Web 性能的文章。其中包括了许多性能相关的主题,如开源工具、缓存、移动网络和应用、自动化、用户体验优化、HTML5、JavaScript、CSS3、指标、ROI和网络协议。本书的视野并不仅仅局限于常规的前端性能优化主题,还涉及了网络环境甚至协议对性能的影响等内容;同时,本书也探讨了若干移动端的性能问题及优化方案。

本书的作者都是全球知名的Web开发和性能维护方面的专家甚至大师,包括Nicholas Zakas、Steve Souders、Stoyan Stefanov等。因此,本书是Web性能领域的百家之言和智慧结晶。

本书适合有一定经验的Web开发者阅读,尤其适合那些致力于全面提升Web性能的专业开发者阅读参考。


对Web开发而言,性能是永远也绕不过去的话题,你正在阅读的,就是一本关注Web性能的书。

与市面上其他关于性能的书不同,本书并不是一个人或一个团队写的,而是由多位活跃在业界最前线的顶级专家的文章集结而成的,可谓是一部Web性能领域的百家之言。从这个角度来讲,本书并不像一部按部就班的教科书,而更像是一个主题论坛。

本书的作者中,有一些是已经名声在外的大师,比如Nicholas Zakas、Steve Souders等;有一些对国内的读者来说可能还比较陌生,但无论你是否听说过他们,相信你都能从这一系列文章中有所收获。

作为一本关注业界前沿的书,本书的视野并不仅仅局限于HTML、JavaScript、CSS及图片等常规的前端性能优化主题,还涉及了网络环境甚至协议对性能的影响等内容。同时,在移动互联网越来越热的今天,本书也探讨了若干移动端的性能问题及优化方案。

通读本书,你可能会注意到前端工程师可以做的事情越来越多,责任也越来越重大。除了传统的浏览器中的世界外,服务器到浏览器之间的传输,乃至整个网站的架构设计,都将少不了前端工程师的参与。幸运的是有如此多经验丰富并且乐于分享的前辈,正是他们的无私分享让本书得以集成,也让我们有机会从中汲取养分,走得更远。

本书适合有一定经验的读者。如果你正关注Web性能问题,那么本书就是为你而写的。限于篇幅,书中对各个问题通常只介绍关键点而很少面面俱到。读过这数十位专家的文章后,或许你马上就会有所启发并在项目中进行实践,也或许在不久的将来,当你遇到类似的问题时,你能从这些专家的经验中找到进一步探索的方向及勇气。


Patrick Meenan

Patrick Meenan(http://blog.patrickmeenan.com/)(@patmeenan)在就职于AOL时创建了WebPagetest(http://www.webpagetest.org/),现就职于谷歌,他的团队正在努力提高Web性能(http://code.google.COM/ speed/)。

Nicholas Zakas

Nicholas C. Zakas(http://www.nczonline.net/)(@ slicknet)是WellFurnished(一个专门帮助您找到漂亮家居装饰的网站)的首席架构师。在此之前,他曾在雅虎工作了近五年,在那里他是表现层架构师、雅虎主页的前端负责人和YUI库的贡献者。他编写了Maintainable JavaScript(2012年O'Reilly出版)、Professional JavaScript for Web Developers(2012年Wrox出版)、Professional Ajax(2007年Wrox出版),以及High Performance JavaScript(2010年O'Reilly出版)。Nicholas大力提倡建立包括渐进增强、可访问性、性能、可扩展性和可维护性在内的最佳实践。他的博客是http://www.nczonline.net/

Guy Podjarny

Guy Podjarny(http://blaze.io/)(@guypod)是Web性能和安全的专家,专注于移动Web性能,Blaze的CTO。最近的10年,Guy在Blaze任职软件架构师和Web应用程序安全专家,他将IBM Rational AppScan产品线从新创发展成了领先的Web Application安全评估工具。Guy已经申请了15项专利,在众多的会议上演说,并发表多篇专业论文。

StoyanStefanov

StoyanStefanov(http://phpied.com/)(@stoyanstefanov)是一名Facebook工程师、前雅虎作者(“JavaScript模式”、“面向对象的JavaScript”)、演讲者(JSConf、Velocity、Fronteers)、工具开发者(Smush.it、YSlow的2.0)和吉他英雄的崇拜者(http://givepngachance.com/)。

Tim Kadlec

Tim Kadlec(http://timkadlec.com)(tkadlec)是一名Web开发人员,在威斯康星州北部工作和生活。他的工作背景非常多样,从小公司到大型出版商以及工业公司,这让他看到,Web技术的精确应用如何影响各种规模的企业。

Tim组织Breaking Development(http://bdconf.com),每两年举行一次,致力于移动设备的网页设计和开发。

他是Implementing Responsive Design: Building Sites for an Anywhere一书的作者。

Brian Pane

Brian Pane(http://www.brianp.net/)(@brianpane)是一位互联网技术与产品的多面手。他曾在迪斯尼、CNET、F5和Facebook工作,一直以来他都尽全力抓住任何机会提高软件性能。

Josh Fraser

Josh Fraser(http://onlineaspect.com/)(@joshfraser)是Torbit的联合创始人兼首席执行官,该公司提供的前端自动优化方案被证实确实能够提高网站的速度。乔希在克莱姆森大学获得计算机科学学士学位,并创办了一家名叫EventVue的公司。目前他住在山景城,并痴迷于速度。

Steve Souders

Steve Souders(http://stevesouders.com/)(@souders)在谷歌(http://www.google. com/)负责网络性能和开放源码。他的书《High Performance Web Sites》阐述了他的性能最佳实践,列居亚马逊的计算机和互联网的畅销书第一位。他后续还有一本《Even Faster Web Sites》为现代Web 2.0应用程序提供了一些性能技巧。Steve 是Firebug的性能分析插件YSlow的创作者,拥有超过2万次的下载量。他还创建了Cuzillion、SpriteMe和Browserscope。他是Velocity(O'Reilly的web性能和运营)大会的联合主席,以及Firebug工作组的联合创始人。他在斯坦福大学教授CS193H高性能网站课程,并经常在各种会议演讲,包括OSCON、Ajax Experience、SXSW和Web 2.0博览会。

Betty Tso

Betty是亚马逊的一名软件开发经理。在此之前,她曾带领雅虎卓越性能优化的工程团队从事于Yahoo的重要性能产品如YSlow和Roundtrip的开发工作。

Betty也是一名Web性能优化领域的传道者。她曾在Velocity大会、雅虎前端峰会和一些大学,如佐治亚理工学院、杜克大学、伊利诺伊大学、德州大学奥斯汀分校、加州大学圣地亚哥分校发表演讲。她也是雅虎Women-in-Tech(一个由600多个成员组成,促进妇女职业生涯成功,促进员工成长,并激发年轻女孩追求技术职业的组织)的联席主席。

Israel Nir

Israel Nir (@shunra) 喜欢创造东西,打散其他东西、代码、数字0X17和弹四弦琴。他还在Shunra公司领导一个团队开发能使应用程序跑得更快的工具。

Marcel Duran

马塞尔·杜兰(http://javascriptrules.com/)目前是Twitter的一名前端工程师,在此之前,他在Yahoo首页和搜索团队负责大流量网站的性能优化,在那里他应用和研究Web性能最佳实践进一步提高网页性能。他在雅虎的最后一个职位是卓越性能优化团队的前端领导者,他全力投入YSlow(现在是他的个人开源项目)以及其他性能工具的开发、研究和宣传。

Éric Daspet

Eric Daspet (http://eric.daspet.name/) (@edasfr) 是一个法国网站顾问。他使用PHP,创立了Paris-Web会议以促进Web质量,并通过组织本地用户组和一本书来推动性能。

Alois Reitbauer

Alois Reitbauer (http://blog.dynatrace.com/) (@aloisreitbauer) 是dynaTrace软件的一名技术战略专家并领导dynaTrace Center of Excellence。作为dynaTrace实验室技术的一个主要贡献者,他影响着公司的未来技术方向。除了工程师的工作,他还帮助财富500强公司实施成功的绩效管理。

Matthew Prince

Matthew Prince (http://www.cloudflare.com/) (@eastdakota)是CloudFlare的联合创始人兼CEO。Matthew在他7岁时写了第一个计算机程序,并一直没有找出bug。在芝加哥大学法学院学习之后,他做了一天的律师就转而成为了一家技术创业公司的创始人。他没有回头。CloudFlare是Matthew的第三次创业。另外,Matthew也作为兼职教授传教互联网法律,同时又是一个认证滑雪教练及圣丹斯电影节的常客。

Buddy Brewer

Buddy Brewer(你可以在twitter上通过@bbrewer找到他)是Log Normal公司的联合创始人,这家公司致力于提供真实用户在等待你的网站打开所花的时间。他已从事多个Web性能问题相关的职位并长达大约10年。

Alexander Podelko

Alex Podelko(http://alexanderpodelko.com/blog/)(@apodelko)在最近的14年里都从事着性能工程师的工作,并为多家公司设计架构。目前他是Technical Staff at Oracle的顾问成员,负责性能测试以及Hyperion的优化。同时,Alex还是Computer Measurement Group(CMG)的一名理事,维护着一系列性能相关的链接和文档。

Estelle Weyl

Estelle Weyl(http://www.standardista.com/) (@estellevw)最开始是从事建筑行业的工作,然后管理过青少年健康工程。在2000年,她自然而然地踏上了Web标准的道路。她曾近担当过Kodakgallery、Yahoo!、Apple以及其他公司的顾问。Estelle在她的博客里提供了许多技术教程,并且为CSS3和HTML5的浏览器支持情况做了详细表格。同时,她还是Mobile HTML5 (O’Reilly, Oct. 2011) 和HTML5 and CSS3 for the Real World (Sitepoint, May 2011)的作者。当不写代码的时候,她会忙着把她停留在20世纪60年代的反潮流房子整理得不那么嬉皮式。

Tony Gentilcore

Tony Gentilcore (@tonygentilcore)是Google的一名软件工程师。他乐于让Web更快,并且最近添加了Google Chrome/WebKit对Web Timing和async scripts的支持。

Aaron Peters

Aaron Peters (http://www.aaronpeters.nl/en/)(@aaronpeters) 是一名来自荷兰的独立Web性能咨询师。他是Red Hot Chili Peppers的歌迷,万一你和他一起参加滑雪比赛,小心他随时踢你屁股。

Matthew Steele

Matthew Steele 同样是来自Google的一名软件工程师,致力于让Web更快。Matthew 曾经致力于Firefox 和 Chrome 上的Page Speed,并为mod_pagespeed贡献过代码,最近还领导了Apache上mod_spdy的设计和开发。

Bryan McQuade

Bryan McQuade (@bryanmcquade)目前任职于Google,带领Page Speed 团队,曾经给许多Web加速项目贡献过代码,包括Shared Dictionary Compression over HTTP和优化Web服务器以更好利用HTTP。

TobieLangel

TobieLangel (http://tobielangel.com/) (@tobie)是来自Facebook的一名软件工程师,也是Facebook的W3C的顾问委员会代表。同时他也是一名热心的开源代码贡献者(https://github.com/tobie),他由于共同维护Javascript框架Prototype而为人熟悉。Tobie最近又开始在blog.tobie.me (http://blog.tobie.me/)写博客。在此之前,他是一名专业的爵士鼓手。

Billy Hoffman

如果Billy Hoffman还相信一件事,那一定是透明化。事实上,他曾经因为这个吃了官司,但那是另一个故事了。作为Zoompf的创始人和CEO,Billy 继续推动透明化。Zoompf的产品通过定位拖慢你的网站的具体因素来让你更清楚地了解你的网站的性能状况。你可以在Twitter上找到该公司(http://twitter.com/zoompf),也可以在Zoompf的博客Lickity Split(http://zoompf.com/blog)上阅读Billy的性能分析文章。

Joshua Bixby

Joshua Bixby (@JoshuaBixby)是Strangeloop (http://www. strangeloopnetworks.com/ )的董事长,这家公司为eBay/Paypal、Visa、Petco、Wine.com和O’Reilly Media等公司提供网站加速解决方案。同时Joshua 还维护Web Performance Today (http://www.webperformancetoday.com/)博客,讨论网站速度、用户行为、性能优化相关的议题和想法。

Sergey Chernyshev

Sergey Chernyshev (http://www.sergeychernyshev.com/) (@sergeyche)组织了纽约Web性能集会,并帮助世界上其他性能爱好者在他们的城市组织集会。Sergey 自愿帮PerfPlanet维护其Twitter账号@perfplanet。同时,他也是开源开发者以及一些Web性能相关工具的作者,包括ShowSlow、SVN Assets、drop-in.htaccess等。

JP Castro

JP Castro (@jphpsf) 是一位来自旧金山的前端工程师。JP痴迷于Web开发,特别是Web性能。他的博客是http://blog.jphpsf.com,也是旧金山性能聚会的组织者之一。当他不讨论性能时,他喜欢和家人呆在一起,去户外运动,喝精酿的啤酒,吃大罐的Nutella,还有玩电视游戏。

Pavel Paulau

Pavel Paulau (@pavelpaulau)是一位来自白俄罗斯明斯克的性能工程师。除了Couchbase ( http://www.couchbase.com )的日常工作,他还是WebPerformance.ru博客 ( http://webperformance. ru/ )的合作作者,并在博客上努力传播速度的重要性。

David Calhoun

David Calhoun (@franksvalli)是一位独立前端开发者,经常来往于美国加利福尼亚和日本。除了是JSMag的社区新闻作者,David还维护着一个博客(http://davidbcalhoun.com/),记录着他的开发和一般生活想法(哲学学位没地方发挥作用……)。

David专注于移动开发和前端性能,当然,还有移动性能。他之前供职于Yahoo!Mobile、CBSi、CNET,偶尔与WebMocha有合作,目前正在与Skybox Imaging合作,开发一个浏览器上的飞行卫星界面。

Nicole Sullivan

Nicole Sullivan ( http://stubbornella.org/ ) (@stubbornella)有多个身份,包括布道者、前端性能顾问、CSS专家、作家。她启动了面向对象CSS的开源项目,对如何为百万级用户和上千页面书写可扩展的CSS这一问题做出了回答。除此之外,她还为W3C重新设计的beta版规范担当顾问,还是图片优化云服务提供商Smush.it的联合创始者。

Nicole对CSS、Web标准、大型商业网站的可扩展前端架构充满激情。她还在全球各地的大会上发表性能相关的演讲,最近的有The Ajax Experience、ParisWeb和Web Directions North。她同时还是Even Faster Websites一书的作者之一,她的博客是stubbornella.org。

James Pearce

James (http://tripleodeon.com/) (@jamespearce)是Facebook Mobile Developer Relations的负责人,定居加利福尼亚,经常出没于全球各地的飞机场。

Tom Hughes-Croucher

Tom (http://tomhughescroucher.com/) (@sh1mmer)是Jetpacks for Dinosaurs公司的首席顾问,这是一家以提升网站速度为目标的公司。Tom为Walmart和MySpace等公司做过顾问。作为一名业界资深人员,Tom曾在诸如Yahoo!、Joyent、NASA、Tesco以及其他许多公司工作过。他还是Up and Running with Node.js 一书的作者之一,目前定居加利福尼亚州的旧金山。

Dave Artz

Dave Artz现在在AOL带领Site Engineering团队。之前他带领过Optimization团队,一个专注于为他现在带领的团队在前端工程、性能、SEO方面制定标准和最佳开发实践的团队。除了管理多个团队,他还继续地开发以下项目:为他的启动库(https://github.com/artzstudio/Boot)开发脚本、CSS、字体加载器,一个jQuery的AMD加载器(https://github.com/artzstudio/jQuery-AMD),以及一个叫Sonar(https://github.com/artzstudio/jQuery-Sonar)的jQuery插件,这个插件利用特殊的“scrollin”和“scrollout”事件,可以很方便地按需加载内容和功能。


王玉林(@非常长),无线工程师,前端翻译小站(www.trans4fun.org)组织者之一,LESSCSS中国社区发起人,目前就职于阿里巴巴无线部门,花名飞长。个人博客:http://veryued.org

吴英杰(@oldj),工程师+科幻迷怪蜀黍,曾参与多本图书的翻译或校对工作,目前就职于阿里巴巴,关注PC及无线端用户体验的度量及改进。个人博客:http://oldj.net

庄婷婷(@竹子的那个叶),花名紫溪,现任职于淘宝UED,从事前端开发工作。游戏、电影、动漫、宅,一个都不能少。

唐云飞(@ liuyunclouder),现任职于淘宝UED做前端开发,花名灵吾,平时喜欢看电影、玩游戏,和基友们打篮球,偶尔玩玩摄影,人称60D(买的相机是佳能60D)。除了前端,工作之余喜欢钻研nodejs、ios。


我希望你会喜欢这本书,如同在编著过程中我很享受和这个行业中最聪明的人并肩战斗一样。

早在2009年12月,我就想总结关于Web性能优化(WPO)的规则。于是,我决定给自己的“每日一篇”设置最后期限(从12月1日至24日),类似 http://www.24ways.org 基督降临节日历。结果是,连续写24篇文章是相当大的挑战,所以我很高兴并十分感激几个同行朋友提供的帮助:Christian Heilmann (Mozilla)、Eric Goldsmith (AOL)和AraPehlivanian (Yahoo!)的2篇文章。

文章被社区热情接纳,随后的一年,在2010年12月,一些读者期待着文章日历的回归。日历也有了新家,在“Planet Performance”的二级域名 http://calendar. perfplanet.com下。而这次,有更多的人愿意提供帮助。各地的开发者,都愿意贡献他们的时间,分享和传播他们的知识,发布新工具,这样能创造出更优秀的24篇文章。这不久将成为该系列的第1卷。

来到2011年12月,我们有这么多好的内容和热情激励我们从12月24日持续至12月31日,甚至最后一天还发表了两篇文章。这就是你手中的Web Performance Daybook第2卷。

我们的WPO社区虽然不大,还很年轻,但它在不断成长,并需要一些社区建设活动的形式来提供营养,如基督降临节日历形式的文章发表。这就是为什么有机会和O’Reilly以及所有32位作者合作如此令人兴奋。我对结果很满意,并且知道在未来的几年中,这两卷书将作为参考读物以及介绍性能工具、研究、技术和方法的书籍。虽然离线技术出版物总是会有内容过时的风险,但是我在最近的会议经常注意到有引用这些日历文章,所以我相信这些知识在相当一段时间内会保持新鲜,甚至其中的一些会注定成为永恒。

享受本书,准备向同行中最聪明的人学习,最重要的是,做好准备,为大家创造更好的Web!

——Stoyan Stefanov


您手中的这本书收录了大量已发表的 Web 性能相关的文章。其中包括了许多性能相关的主题,如开源工具、缓存、移动网络和应用、自动化、用户体验优化、HTML5、JavaScript、CSS3、指标、ROI和网络协议。这些文章的作者形形色色,有全球最大互联网公司的职员,也有独立顾问。作者们代表至少7家Web性能初创公司:Blaze、Cloud-Flare、Log Normal、Strangeloop、Torbit、Turbobytes和Zoompf。主题和贡献者范围之广令人印象深刻。但真正给我留下深刻印象的是那些贡献者,除了日常工作,他们中有的人参与了一个或多个开源项目、有的人写博客、写书、有的人在会议上发表演说、组织会议或运行非营利性组织。有些人甚至都有涉及。在埋头调试各种主要浏览器中的JavaScript,或跟踪引起页面加载时间衰退的问题一整天后,究竟是什么让这些人在“闲暇之余”对Web性能社区做出贡献?这里有一些我收到的答复。

很多从事互联网工作的人都是在工作中掌握技能。Web相关的东西要么没有出现在我们的大学课程上,要么我们学过的并不适用于现在的工作。这种在工作中的学习是一个漫长的、涉及很多试错的过程。分享最佳实践,可以提高团队IQ,并让新手可以更快速地掌握技能。

错误发生在试错的过程中。我们都曾经历过在凌晨或一连好几天苦苦攻克一个问题,往往经过一个漫长的排除问题的过程勉强解决了问题。值得庆幸的是,我们的社区意识不会让我们默默地站在一旁看同行重蹈覆辙。分享我们的解决方案可以让其他人避免犯同样的错误。

由于天性,开发者都痴迷于优化。我们都着力追求速度最快的代码、最高效的算法、最具弹性的架构。这种痴迷不只限于我们的网站,我们希望每一个网站都得以优化。做到这一点的最好办法是分享。

最后,有些人真的很乐于帮助他人。想象一下吧,当某个人意识到他省下了一周的工作或他们的网站访问速度可以快两倍……,他们的笑容让我们觉得为社区的成长尽了一份力。

作为分享精神的见证,作者们把这本书的版税捐献给了 WPO 基金会(一个支持Web性能社区的非营利性组织)。因此,你可以享受摆在眼前的这些文章,不仅因为这些它们是全球最好的Web性能建议,也因为它们来自作者对Web性能社区的无私奉献。享受吧!

——Steve Souders


作者:Patrick Meenan

我想借着今年的这次机会向大家介绍一下WebPageTest是如何从浏览器获取性能数据的。虽然它与Windows下一些工具的技术原理大同小异,但本章介绍的内容并不能代表这些工具的工作原理。

首先,请看图1-1,这张图可以帮助我们从浏览器端理解Windows的网络堆栈。

图1-1 从浏览器的角度看Windows网络堆栈

不管是什么浏览器,只要运行在Windows下,体系结构几乎就如图1-1描述的一样,所有的传输都是通过Windows Socket API完成的,即Windows下几乎所有应用程序都使用TCP/IP协议,如图1-1描述。

WebPageTest工作的关键是能够拦截任意函数调用和检查,甚至可以中途改变请求和响应(也可以选择完全不传输)。很幸运,有人已经做了绝大部分重要的工作,并且提供了一个非常优秀的开源库(http://newgre.net/ncodehook),有了这个库,你就不需要关注实现的细节了,但你还是可以了解一下工作原理。

这是一件非常细致的事情,稍不留神就会出岔子,但是使用定义良好的函数(如全部的Windows API),你就可以轻松地拦截任何你想拦截的内容。

这么做有一个缺点,就是你只能把调用重定向到运行在同一个进程下的代码,如果这些代码是你自己写的,那就没什么问题,但如果你要监测那些不受自己控制的软件的话就不太好了,反而可能还会带来一些麻烦。

很幸运,Windows提供了几种向进程中注入任何代码的途径。http://www.codeproject. com/KB/threads/winspy.aspx这里介绍了几种不同方法,当然还有很多其他方法,但是大部分方法这里都有了。有些方法可以把你的代码插入到每一个进程中,但是我想要更有针对性一点的方法,比如仅仅使用我们感兴趣的浏览器作为分析工具。所以经过一些错误尝试后,我最终决定使用CreateRemoteThread/LoadLibrary方法,这个方法基本可以允许你强制任何进程加载任意dll文件或者可执行代码(当然,前提是你有足够的权限)。

现在我们可以拦截任意函数调用了,它变成了一个可以识别指定函数的功能,最好是所有浏览器共用一份代码,这样就可以尽可能多地重用代码了。在WebPageTest中,如果想要拦截所有Winsock调用,我们需要解析主机名,连接套接字以及读写数据(见图1-2)。

图1-2 浏览器架构

这赋予了我们访问所有浏览器网络通信的权限,意味着我们完全可以监测浏览器在做什么。除了必须解码原始字节流以外,其他实现都很简单,它还提供了一个跨浏览器的统一度量方式。SSL添加了一点混淆,所以我们也需要拦截浏览器使用各种SSL库的调用,以便我们可以看到未加密的数据。Chrome的操作可能有点小麻烦,因为对应的库被编译到Chrome的代码里面了。但是很幸运,它们在每一次构建的时候都打上了调试标示符号,所以我们还是可以在内存中找到代码。

同样的方法用于拦截浏览器的绘制调用,就可以得知浏览器是何时把内容绘制到屏幕的(用于开始渲染测量)。

WebPageTest使用BSD协议,所以不论作为什么用途,都欢迎各位重用这里面的代码。项目存放在Google Code上(http://code.google.com/p/webpagetest/),下面还有一些你可能感兴趣的文件。

非常幸运,浏览器已经开始以标准的形式开放更多有趣的信息了,随着W规范的发展,你或者是你最终的用户都可以通过JavaScript直接从浏览器中获取到很多这类信息。

访问http://calendar.perfplanet.com/2011/webpagetest-internals即可评论本章。初次发布于2011 年12 月1 日。


作者:Nicholas Zakas

在Web开发人员使用的工具中,Web Storage(http://dev.w3.org/html5/webstorage/)迅速成为了HTML5新增的最受欢迎的功能。具体来说,localStorage提供了快速简单的客户端数据存储功能,可以跨多个会话存储数据,这使得localStorage在世界各地Web开发人员中被广为应用。通过使用简单的键值接口,我们看到很多网站以各种独特而有趣的方式应用localStorage这一技术。

在我了解的案例中,Google/Bing的这种方式似乎越来越受人们的欢迎。部分原因是由于HTML5 application cache使用困难,部分原因是该技术得到了Steve Souders和其他人的青睐。事实上,随着我越来越多地和人们提及localStorage以及用它来存储UI相关信息是多么的有用,我发现更多人开始尝试这种技术。

我发现一个令人费解的现象,人们在使用localstorage时有一个内定不成文的假设:从localStorage读取数据开销不大。我曾经从其他开发者那里听到传言说遇到异常的性能问题,所以我设计了一个实验来量化localStorage的性能特点,以确定用它读取数据的实际成本。

不久前,我创建并共享了一个简单的基准测试,来测量从localStorage取值和从一个对象属性取值的性能。有人基于这个测试做了改良,并开发了更可靠的版本(http://jsperf.com/localstorage-vs-objects/10)。最终结果是:每个浏览器中,从localStorage读取数据比从对象属性中读取相同数据慢几个数量级。到底有多慢呢?请看图2-1所示(数字越高越好)。

图2-1 基准测试

看了这个图后,你可能会感到困惑,因为它似乎没有展示出从localStorage中读取数据的结果。事实上它被展现出来了,你看不到它的原因是这一数字实在太小,在图示比例上甚至不可见。除了Safari 5可以显示实际的localStorage的读取数据结果,所有其他浏览器的巨大差异使得你根本不可能在这张图上看到实际数据。当我调整y轴的值后,你才可以看到不同浏览器中的测量结果。

通过改变y轴的比例,现在你可以看到从local Storage和从对象属性读取数据的真实对比(见图2-2)。可以看出,结果仍然如此,几乎到了滑稽的程度,这是为什么呢?

图2-2 测试结果

为了保持跨浏览器会话,localStorage的数据被写入磁盘中。这意味着当你从localStorage中读取数据时,你实际上是从硬盘驱动器上读取这些字节。读写硬盘开销高昂,特别是相对于读写内存来说。从本质上讲,这正是我的基准测试所测试的内容,即从缓存(对象属性)读取数据和从磁盘(localStorage)读取数据的速度比较。

更有趣的是,localStorage按源存储数据,这意味着,在同一时间内,浏览器中的多个标签页可以访问相同的localStorage数据。

这对于那些需要弄明白如何实现各标签页同步访问localStorage的浏览器开发商来说十分头疼。当需要从localStorage中读取数据时,浏览器首先需要停下来看看是否有其他标签页正在访问同一数据区域。如果是的话,浏览器必须等到之前的访问操作完成,才可以读取该值。

因此,与从localStorage读取数据相关的延迟是不定的,它在很大程度上取决于在那个时间点上浏览器还在进行的其他操作。

既然从localStorage读取数据有一定开销,那么这会怎样影响你如何使用这一技术呢?在下结论之前,我运行了另一个基准测试(http://jsperf .com/localstorage-string- size),以确定从localStorage读取不同大小数据的效果。我们保存4种不同大小的字符串(100个字符、500个汉字、1000个字符和2000个字符)到localStorage中,然后把它们读取出来。结果有点令人惊讶,在所有浏览器中,读取数据量的大小不会影响读取速度的快慢。

我测试了很多次,并恳请我的Twitter粉丝提供更多的信息(https://twitter.com/ slicknet/status/139475625793699840)。可以肯定的是,对于不同的浏览器会有些许差异,但这些差异都不大,并没有实质性的不同。我的结论是:从单一localStorage键值中读取的数据量对速度没有影响。

我又进行了另一个基准测试(http://jsperf.com/localstorage-string-size-retrieval)来检验我的新结论,最好尽可能地减少读取数据的次数。和此前的基准测试结果类似,在大多数浏览器中,读取100个字符10次比一次读取10 000字符慢90%左右。

鉴于此,从localStorage读取数据的最佳策略是使用尽可能少的键值,存储尽可能多的数据。因为读取10个字符和读取2000个字符所需时间大致是相同的,所以你应该尝试把尽可能多的数据保存为一个键值对应的值。每次调用getItem()(或从localStorage读取属性)都会增加时耗,所以一定要确保每次访问读取数据最大化。对于任何一个变量或对象属性,你越快将它读取到内存,后续的所有操作也会越快。

这篇文章一经发表就引发了大量围绕localStorage性能的讨论。讨论最开始出现在Mozilla 的Chris Heilmann的博客文章中,题为“localStorage没有简单的解决方案”。在文章中,Chris认为localStorage作为一个整体存在性能问题。在很多博文讨论(其中也包括我的)之后,我最终能够联系上Firefox负责实现localStorage的工程师Jonas Sicking。事实上,localStorage所存在的性能问题并不只是比从对象读取数据花费时间长一些那么简单。问题的关键是,localStorage是一个同步API,这本身就使浏览器实现这个API时捉襟见肘。所有的localStorage数据都存储在磁盘文件上。这意味着,为了让您可以用JavaScript访问这些数据,浏览器必须先将该文件读取到内存中。当读取操作发生时性能问题便产生了。当第一次访问localStorage就可能产生性能问题,但在随后的读取操作中浏览器有可能会冻结。在处理少量数据时,这可能不是一个大问题,但如果你已经达到5 MB限制时,就会有明显的影响。Firefox采纳的另一种解决方案,是在加载页面的同时读取localStorage数据。这将确保之后对localStorage的访问最快,并有可预测性。这种方法的缺点是对页面加载时间造成不利影响。到我写这篇文章之时,这一问题仍然没有被解决。有人呼吁用一个全新的API来代替localStorage,其他的人则试图修复现有API的问题。不管发生什么情况,不久的将来仍会有客户端数据存储领域的更多研究。不管发生什么情况,最近一段时间内,我们仍然需要在客户端数据存储方面做更多的研究。

如要评论本章,请访问http://calendar.perfplanet.com/2011/localstorage- read-performance/。最初发表于2011 年12 月2 日。


相关图书

网站性能监测与优化
网站性能监测与优化

相关文章

相关课程