OneAPM大讲堂 | 提高JavaScript性能的30个技巧
文章系国内领先的 ITOM 管理平台供应商 OneAPM 编译呈现。
您是网站管理员还是网页开发人员?想创建超快速的网站吗?
今天我们来看看 JavaScript,这项神奇而又复杂的技术。它使网站内容更加丰富,但常常出现的运行性能问题又降低了用户的体验。事实已经证明,最佳的终端用户体验能提升网站的转换率、Google搜索排名以及访问者的满意度。高性能的JavaScript意味着会给您和您的公司带来更多更好的业务。
下面我们介绍提高 JavaScript 性能的一些技巧。同样地,这或许可以帮助网站管理员和网站开发人员创建快速的网站,并提供一流的用户体验。
技巧 #1 – 评估局部变量
(http://blogs.msdn.com/b/ie/archive/2006/08/28/728654.aspx)
主要针对IE而言,由于局部变量的查找是从最特定作用域到最大作用域,且可以通过多个域层级,所以这种查找会导致查询到通用的结果。在定义函数作用域的时候,如果一个局部变量在之前没有进行过var变量声明, 那么此处一定要在变量名前加上var关键字以定义其当前的作用域和防止查询,从而提高代码的速度。
技巧 #2 – 创建代码快捷方式以加速编码
对于使用频繁的有用代码,可以通过为较长的代码创建快捷方式来加快编码过程,例如 document.getElementById。 通过创建一个快捷方式,编写较长的脚本便不会耗时太久,并且可以节省整个过程的时间。
技巧 #3 – 在将元素片段添加到DOM之前对其实施操作
(http://www.jquery4u.com/dom-modification/improve-javascript-performance)
在创建 DOM 的元素节点之前,请确保已经执行了所有的操作,以提高 JavaScript 的性能。 这样就无需再摒弃 Prepend和 Append 的 jQuery APIs 了。
技巧 #4 – 使用Minification保存字节
(http://sixrevisions.com/web-development/10-ways-to-improve-your-web-page-performance)
通过删除字符(标签,源代码文档,空格等)而不改变文件功能的方式减小 JavaScript 文档。
有许多缩小工具可以用来完成这个过程,并且还可以将缩小复原。 缩小是从源代码中删除所有不必要的字符而不改变其功能的过程。
技巧 #5 – 除非必要,否则不要使用嵌套循环
减少不必要的循环,例如 for 和 while 循环,以保持 JavaScript 的线性,并避免需要遍历数千个对象。无用的循环可能会导致浏览器处理代码时更困难,从而减缓速度。
技巧 #6 – 缓存对象以提高性能
很多时候,会重复使用脚本来访问某个对象。 将重复访问的对象存储在用户定义的变量中,并且之后在引用该对象时使用此变量,可以立刻实现性能提升。
技巧 #7 – 使用.js文件来缓存脚本
(http://www.javascriptkit.com/javatutors/efficientjs.shtml)
使用这种技术可以实现性能提升,因为它允许浏览器只加载脚本一次,当页面被重新加载或重新访问时只需要从缓存中调用脚本即可。
技巧 #8 – 将JavaScript放置到页面的底部
将脚本尽可能放在页面底部的位置会加快渲染进度,同时也会增加下载并行度。 其结果是页面看起来加载得更快了,并且在某些情况下,它也可以减少所需要的总的代码量。
技巧 #9 – 使用jQuery作为框架
jQuery 用于 HTML 脚本编程,是一个易于使用的 JavaScript 库,可以帮助任何网站实现加速。 jQuery 提供了大量可以快速使用的插件,即使是新手程序员也不成问题。
技巧 #10 – 使用Gzip压缩文件
(http://devmoose.com/coding/10-ways-to-instantly-speed-up-your-website)
使用 GZip 可以明显地降低 JavaScript 文件的大小,节省带宽,并加快响应时间。 有时 JavaScript 文件非常大,如果没有经过压缩,它可能会造成网站瘫痪。较小的文件能提供更快、更令人满意的网页体验。
技巧 #11 – 不要使用With关键字
(http://blogs.msdn.com/b/ie/archive/2006/08/28/728654.aspx)
“With”这个关键词被认为是害群之马,因为它本身存在一些让人倍感沮丧的缺陷。虽然有了它使用局部属性的过程会变得更加简单,但当在其他作用域中查找变量时,使用With会增大代价。
技巧 #12 – 尽量减少对HTTP的请求
(http://www.websiteoptimization.com/speed/tweak/http)
通过结合外部文件和直接在 XHTML 页面中嵌入 JavaScript 来尽量减少对 HTTP 返回页面的请求。 每一个特定的 HTTP 请求传输至服务器端都会导致大量的时延。
技巧 #13 – 实现事件代理
使用事件代理将会使利用单个事件处理程序来为整个页面管理某种事件类型变得更加容易。 如果不使用事件代理,大型的 Web 应用程序可能会由于过多的事件处理程序而停止工作。 实现事件代理的好处包括: 需要管理的功能更少,代码和 DOM 之间的联系更少,进程所需的内存更少。
技巧 #14 – 不要重复使用相同的脚本
(http://www.abhishekbharadwaj.com/2010/12/speed-up-your-website-avoid-duplicate-scripts)
重复的脚本对性能会造成显著的影响。重复的脚本会创建不需要的HTTP请求,尤其是在IE浏览器中。在HTML页面中使用脚本标签,可以帮助避免意外地生成重复的脚本。
技巧 #15 – 移除双美元符号$$
(http://www.mellowmorning.com/2008/05/18/javascript-optimization-high-performance-js-apps)
当考虑提升网站的速度时,使用双美元符号$$并不是必要的选择。
技巧 #16 – 创建变量引用
(http://mondaybynoon.com/2009/04/27/a-couple-of-quick-tips-for-javascript-optimization)
当需要重复使用某个节点时,最好为该节点定义一个变量,使用节点时对变量进行引用,而不是反复来回操作。针对少量这样的节点,也许这并不能显著地提升性能,但是在节点数量很大时,这种方法就可以带来明显的影响。
技巧 #17 – 提高Object Detection的速度
(http://dean.edwards.name/weblog/2005/12/js-tip1)
一种更有效的使用 Object Detection 的方法是使用基于对象检测而动态创建的代码,而不是在函数内部去执行对象检测。
技巧 #18 – 编写有效的循环
(http://robertnyman.com/2008/04/11/javascript-loop-performance)
根据浏览器的不同,不同的循环实现方法也会对网站的性能产生很大的影响。 编写不正确的循环可能会降低那些具有大访问量的页面的响应速度,或者导致同时运行多个循环。
技巧 #19 – 缩短作用域链
全局作用域通常较慢,因为每次执行函数的时候,它会引发创建一个临时的调用作用域,JavaScript 会在作用域链中搜索第一个对象,如果找不到该变量,则会遍历链直到搜索到全局对象。
技巧 #20 – 对NodeLists直接索引
NodeLists 是动态的,会占用大量的内存,因为当底层的文档对象更改时它们也会被更新。 直接对列表进行索引会速度更快,因为此时浏览器不需要创建节点列表对象。
技巧 #21 – 不要使用‘eval’
虽然“eval”函数是运行任何代码的好方法,但是在实际运行时,传递给 eval 函数的每个字符串都需要进行解析和执行。 每次调用eval函数的时候,都会引入这些时间开销。
技巧 #22 – 使用函数内联
(https://dl.acm.org/citation.cfm?id=844097)
函数内联有助于减少函数调用的成本,并用被调用的函数体替换函数调用。 在 JavaScript 中执行函数调用是一个高成本的操作,因为需要执行几个准备步骤:为参数分配空间,复制参数以及解析函数名称。
技巧 #23 – 实现 Common Sub-expression Elimination (CSE)
(http://sunilkumarn.wordpress.com/2010/10/19/common-subexpression-elimination-cse)
Common Sub-expression Elimination (CSE)是一种以性能为目标的编译器优化技术,用于搜索相同的表达式对象,并用保存着计算值的单个变量替换它们。可以认为,对通用子表达式使用单个的局部变量总是比保持代码不变具有更快的速度。
技巧 #24 – 离线构建DOM节点以及所有子节点
当向站点添加复杂的内容(例如表格)时,通过离线的方式添加复杂的子树可以提升性能。
技巧 #25 – 尽量不要使用全局变量
由于脚本引擎需要搜索作用域,所以当从函数内部或其他作用域内引用全局变量时,如果局部作用域丢失,全局变量将被销毁。如果全局作用域中的变量并不一直存在于脚本的生命周期,则可以提升性能。
技巧 #26 – 使用原始的函数操作而不使用函数调用
通过使用等效的原函数而非函数调用,可以在对性能有关键影响的循环和函数中实现速度提升。
技巧 #27 – 不要一直保留对其他文档的引用
(http://dev.opera.com/articles/view/efficient-javascript/?page=4#docreferences)
当脚本结束后不再保留对其他文档的引用可以实现更快的性能。因为对其他文档中的对象进行的任何引用不会被保存在整个 DOM 树中,并且脚本环境也不会一直保留在内存中。 因此文档本身不用再被加载。
技巧 #28 – 使用XMLHttpRequest
(http://dev.opera.com/articles/view/efficient-javascript/?page=4#docreferences)
XMLHttpRequest 有助于减少来自服务器端的内容数量,并且避免在页面加载的间隙销毁和重新创建脚本环境对性能造成的影响。一定要确保支持 XMLHttpRequest,否则可能会导致问题和混淆。
技巧 #29 – 避免使用try-catch-finally结构
(http://dev.opera.com/articles/view/efficient-javascript/?page=2)
每当执行 catch 子句时,捕获的异常对象被分配给一个变量,“try-catch-finally”会在运行时在当前作用域中创建一个新变量。 许多浏览器不能有效地处理这个过程,因为变量是在运行时被创建和销毁的。避免使用它!
技巧 #30 – 不要误用 for-in
(http://dev.opera.com/articles/view/efficient-javascript/?page=2)
由于“for-in”循环需要脚本引擎构建包含所有可枚举属性的列表,因此 for 循环内的代码是不会修改这个列表的。 在 for 循环内部,预先计算出列表的长度并赋给变量 len,然后进行迭代。
后续我们还会发布有关性能管理的系列帖子...敬请关注!
Browser Insight 是一个基于真实用户的 Web 前端性能监控平台,能够帮大家定位网站性能瓶颈,网站加速效果可视化;支持浏览器、微信、App 浏览 HTML 和 HTML5 页面。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
来源:http://blog.oneapm.com/apm-tech/802.html