O’Reilly Media, Inc.介绍
O’Reilly Media通过图书、杂志、在线服务、调查研究和会议等方式传播创新知识。自1978年开始,O’Reilly一直都是前沿发展的见证者和推动者。超级极客们正在开创着未来,而我们关注真正重要的技术趋势——通过放大那些“细微的信号”来刺激社会对新科技的应用。作为技术社区中活跃的参与者,O’Reilly的发展充满了对创新的倡导、创造和发扬光大。
O’Reilly为软件开发人员带来革命性的“动物书”;创建第一个商业网站(GNN);组织了影响深远的开放源代码峰会,以至于开源软件运动以此命名;创立了Make杂志,从而成为DIY革命的主要先锋;公司一如既往地通过多种形式缔结信息与人的纽带。O’Reilly的会议和峰会集聚了众多超级极客和高瞻远瞩的商业领袖,共同描绘出开创新产业的革命性思想。作为技术人士获取信息的选择,O’Reilly现在还将先锋专家的知识传递给普通的计算机用户。无论是通过书籍出版、在线服务或者面授课程,每一项O’Reilly的产品都反映了公司不可动摇的理念——信息是激发创新的力量。
业界评论
“O’Reilly Radar博客有口皆碑。”
——Wired
“O’Reilly凭借一系列(真希望当初我也想到了)非凡想法建立了数百万美元的业务。”
——Business 2.0
“O’Reilly Conference是聚集关键思想领袖的绝对典范。”
——CRN
“一本O’Reilly的书就代表一个有用、有前途、需要学习的主题。”
——Irish Times
“Tim是位特立独行的商人,他不光放眼于最长远、最广阔的视野并且切实地按照Yogi Berra的建议去做了:‘如果你在路上遇到岔路口,走小路(岔路)。’回顾过去Tim似乎每一次都选择了小路,而且有几次都是一闪即逝的机会,尽管大路也不错。”
——Linux Journal
谨以此书献给我的家人,妈妈、爸爸和Grey,
是你们的爱和支持使我走过这些岁月。
译者序
这是一本关于JavaScript性能的书。
在Web应用日趋丰富的今天,越来越多的JavaScript被运用在我们的网页中。随着用户体验被日益重视,前端性能对用户体验的影响开始备受关注,而引起性能问题的因素相对复杂,因此它很难得到全面的解决。这本书是一个契机,它尝试着从多个方面综合分析导致性能问题的原因,并给出适合的解决方案,帮助我们改善Web应用的品质。
这本书页数不多,但它承载着JavaScript性能方面最为宝贵的经验。不仅从语言特性、数据结构、浏览器机理、网络传输等层面分析导致性能问题的原因,还介绍了多种工具来帮助我们提升开发过程和部署环节的工作效率。
本书作者Nicholas C. Zakas是一位经验丰富的前端专家,他的许多研究(www.nczonline. net)对前端业界的贡献让我们受益匪浅。本书的另外五位特约作者均为各自领域的专家,他们的专业技能和知识的融入使得本书内容更为充实,更具实用价值。
特别感谢赵泽欣(小马),他为审阅译文花了大量的时间和精力,他的耐心和细致让我十分敬佩。感谢朱宁(白鸦)和周筠老师的引荐让我得以参与本书的翻译。还要感谢博文视点的编辑们在本书翻译过程中给予的极大理解和帮助。
我们在本书翻译过程中力求保持行文流畅,但纰漏在所难免,恳请广大读者批评指正。关于本书的任何意见或想法,欢迎发送邮件至hpj.feedback@gmail.com。
最后,希望本书能帮助业界同仁打造出性能更为卓越的Web产品。
丁琛
前言
Preface
当 JavaScript 作为 Netscape Navigator 浏览器的一部分在1996年首次出现时,性能问题并不重要。当时的互联网仍处在发展初期,各个方面都很慢。从拨号上网到低配置的家用电脑,上网冲浪往往比任何事情都需要耐心。人们都做好了等待网页加载的心理准备,页面加载能完成就是一件值得庆祝的事了。
JavaScript 最初的目标是改善网页的用户体验。JavaScript 能代替服务器处理页面中类似表单验证的简单任务,这样做节省了与服务器连接的大量时间。想象一下当你填完一个很长的表单,提交后等待了30~60秒,却得到一个字段出错的信息是什么感觉。显而易见,JavaScript 为早期的互联网用户节省了很多时间。
互联网的发展
The Internet Evolves
在接下来的10 年里,电脑和互联网不断发展。首先,两者都变得更快。高速的微处理器,内存的廉价供应,以及光纤连接的出现将互联网推向了一个新的时代。随着高速网络的普及,网页开始变得丰富,并且承载着更多的信息和多媒体内容。Web 从简单的关联文档演变成了各式各样的设计和界面。一切都变了,除了一样东西,那就是 JavaScript。
这项曾用于节省服务器消耗的技术日益普及,但代码也从数十行的发展到成百上千行。IE 4 和动态 HTML译注 (改变页面显示而无需重新加载的技术)的推出更是使得网页中的 JavaScript 代码量只增不减。
最近一次浏览器的重大更新是文档对象模型(DOM)的推出,这是一个被IE 5、Netscape 6及Opera所一致接受的动态HTML接口。紧接着,JavaScript被标准化,并推出了ECMA-262
第三版。随着所有浏览器都支持 DOM,同时(或多或少)提供了对相同版本 JavaScript 的支持,Web 应用平台诞生了。尽管有如此巨大的飞跃,有了编写 JavaScript 的通用 API,但是负责执行代码的 JavaScript 引擎几乎没有变化。
为什么优化是必要的
Why Optimization Is Necessary
在 1996 年,JavaScript 引擎只要能支持页面里数十行的 JavaScript 代码就好, 而今天,却运行着成千上万行 JavaScript 代码的 Web 应用。从许多方面来说,如果不是因为浏览器自身在语言管理和基础设施方面的落后,JavaScript 本可能取得更大规模的成功。IE 6 就是一个明证,发布之初,它的稳定性和性能都被人们称颂,但后来却因为自身的 Bug 和反应迟钝而被痛批为令人讨厌的 Web 应用平台。
事实上,IE 6并没有变慢,它只是被寄予了厚望。2001年IE 6刚发布时出现的各类早期Web应用比2005年后出现的应用更轻量,JavaScript代码也远没有那么多。JavaScript 代码数量的增长带来的影响变得明显,IE 6 的 JavaScript 引擎吃不消了,原因在于它的“静态垃圾回收机制”译注 。该引擎监视内存中固定数量的对象来确定何时进行垃圾回收。早期的 Web 应用开发人员很少会遇到这个极限值,随着更多的JavaScript代码产生越来越多的对象,复杂的 Web 应用开始频繁遭遇这个门槛。问题变得清晰起来:JavaScript开发人员和 Web 应用都在发展,而 JavaScript 引擎却没有。
尽管其他浏览器有着更加完善的垃圾回收机制和更好的运行性能,但大多数仍然使用 JavaScript 解释器来执行代码。解释性代码天生就没有编译性代码快,因为解释性代码必须经历把代码转化成计算机指令的过程。无论解释器怎样优化和多么智能,它总是会带来一些性能损耗。
编译器已经有了各种各样的优化,使得开发人员可以按照他们想要的方式编写代码,而不需要担心是否是最优。编译器可以基于词法分析去判断代码想实现什么,然后产生出能完成任务的运行最快的机器码来进行优化。解释器很少有这样的优化,这很大程度上意味着,代码怎么写,就被怎么执行。
实际上,通常在其他语言中由编译器处理的优化,在 JavaScript 中却要求开发人员来完成。
下一代JavaScript引擎
Next-Generation JavaScript Engines
2008 年,JavaScript 引擎迎来了第一次大的性能升级。Google 发布了全新的浏览器,名为 Chrome。Chrome 是第一款采用优化后的 JavaScript 引擎的浏览器,该引擎的研发代号为 V8。V8 是一款为 JavaScript 打造的实时(JIT)编译引擎,它把 JavaScript 代码转化为机器码来执行,所以给人的感觉是JavaScript的执行速度超快。
其他浏览器紧跟着也优化了它们的 JavaScript 引擎。Safari 4 发布了名为 SquirrelFish Extreme(或称为 Nitro)的 JIT JavaScript 引擎,而Firefox 3.5 的 TraceMonkey 引擎对频繁执行的代码路径做了优化译注 。
这些全新的 JavaScript 引擎带来的是编译器层面的优化,这也是它应该做的。或许有一天,开发人员完全无须关心代码的性能优化。可是,那一天还未到来。
性能依然需要关注
Performance Is Still a Concern
尽管核心 JavaScript 的执行速度已经有所提高,但 JavaScript 仍然有多个方面的问题在新的引擎中没有被处理。网络延迟导致的滞缓和影响页面外观的操作尚未得到浏览器的充分优化。尽管诸如函数内联、代码合并以及字符串连接算法等简单的优化很容易通过编译器进行优化,但对动态且多层结构的 Web 应用程序来说,这些优化只能解决部分的性能问题。
然而全新的 JavaScript 引擎让我们似乎看到未来高速互联网的模样,在可预见到的未来,当今的性能话题仍然具有相关性和重要性。
本书中讨论的技术和方案涉及 JavaScript 的各个方面,内容涵盖运行时间、下载、DOM操作、页面生存周期等。这些话题仅仅是一小部分,它们相关的核心(ECMAScript)性能可能随着JavaScrip