- 浏览: 749261 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
hsl313:
源码还有得下载吗?
利用AMF数据封装与Flash 进行Socket通讯 -
zhang5476499:
已看,谢谢讲解。
Mock单元测试 -
Buydeful:
...
关于JSP或HTML的命名规范 -
lliiqiang:
单一登陆最好采用踢掉方法,如果忘记退出,可以从别的地方控制方式 ...
Jquery选择器大全 -
lliiqiang:
web代码由后台动态生成,这种动态方式多种多样,多提供几种标准 ...
Jquery选择器大全
http://www.iteye.com/topic/126859
首先,与其他语言不同,JS的效率很大程度是取决于JS engine的效率。除了引擎实现的优劣外,引擎自己也会为一些特殊的代码模式采取一些优化的策略。例如FF、Opera和Safari的JS引擎,都对字符串的拼接运算(+)做了特别优化。显然,要获得最大效率,就必须要了解引擎的脾气,尽量迎合引擎的口味。所以对于不同的引擎,所作的优化极有可能是背道而驰的。
而如果做跨浏览器的web编程,则最大的问题是在于IE6(JScript 5.6)!因为在不打hotfix的情况下,JScript引擎的垃圾回收的bug,会导致其在真实应用中的performance跟其他浏览器根本不在一个数量级上。因此在这种场合做优化,实际上就是为JScript做优化!
所以第一原则就是只需要为IE6(未打补丁的JScript 5.6或更早版本)做优化!
如果你的程序已经优化到在IE6下可以接受的性能,那基本上在其他浏览器上性能就完全没有问题。
因此,注意我下面讲的许多问题在其他引擎上可能完全不同,例如在循环中进行字符串拼接,通常认为需要用Array.join的方式,但是由于SpiderMonkey等引擎对字符串的“+”运算做了优化,结果使用Array.join的效率反而不如直接用“+”!但是如果考虑IE6,则其他浏览器上的这种效率的差别根本不值一提。
JS优化与其他语言的优化也仍然有相同之处。比如说,不要一上来就急吼吼的做优化,那样毫无意义。优化的关键,仍然是要把精力放在最关键的地方,也就是瓶颈上。一般来说,瓶颈总是出现在大规模循环的地方。这倒不是说循环本身有性能问题,而是循环会迅速放大可能存在的性能问题。
所以第二原则就是以大规模循环体为最主要优化对象。
以下的优化原则,只在大规模循环中才有意义,在循环体之外做此类优化基本上是没有意义的。
目前绝大多数JS引擎都是解释执行的,而解释执行的情况下,在所有操作中,函数调用的效率是较低的。此外,过深的prototype继承链或者多级引用也会降低效率。JScript中,10级引用的开销大体是一次空函数调用开销的1/2。这两者的开销都远远大于简单操作(如四则运算)。
所以第三原则就是尽量避免过多的引用层级和不必要的多次方法调用。
特别要注意的是,有些情况下看似是属性访问,实际上是方法调用。例如所有DOM的属性,实际上都是方法。在遍历一个NodeList的时候,循环条件对于nodes.length的访问,看似属性读取,实际上是等价于函数调用的。而且IE DOM的实现上,childNodes.length每次是要通过内部遍历重新计数的。(My god,但是这是真的!因为我测过,childNodes.length的访问时间与childNodes.length的值成正比!)这非常耗费。所以预先把nodes.length保存到js变量,当然可以提高遍历的性能。
同样是函数调用,用户自定义函数的效率又远远低于语言内建函数,因为后者是对引擎本地方法的包装,而引擎通常是c,c++,java写的。进一步,同样的功能,语言内建构造的开销通常又比内建函数调用要效率高,因为前者在JS代码的parse阶段就可以确定和优化。
所以第四原则就是尽量使用语言本身的构造和内建函数。
这里有一个例子是高性能的String.format方法。String.format传统的实现方式是用String.replace(regex, func),在pattern包含n个占位符(包括重复的)时,自定义函数func就被调用n次。而这个高性能实现中,每次format调用所作的只是一次Array.join然后一次String.replace(regex, string)的操作,两者都是引擎内建方法,而不会有任何自定义函数调用。两次内建方法调用和n次的自定义方法调用,这就是性能上的差别。
同样是内建特性,性能上也还是有差别的。例如在JScript中对于arguments的访问性能就很差,几乎赶上一次函数调用了。因此如果一个可变参数的简单函数成为性能瓶颈的时候,可以将其内部做一些改变,不要访问arguments,而是通过对参数的显式判断来处理。
比如:
代码
这个sum通常调用的时候个数是较少的,我们希望改进它在参数较少时的性能。如果改成:
代码
其实并不会有多少提高,但是如果改成:
代码
就会提高很多(至少快1倍)。
最后是第五原则,也往往是真实应用中最重要的性能障碍,那就是尽量减少不必要的对象创建。
本身创建对象是有一定的代价的,但是这个代价其实并不大。最根本的问题是由于JScript愚蠢之极的垃圾回收调度算法,导致随着对象个数的增加,性能严重下降(据微软的人自己说复杂度是O(n^2))。
比如我们常见的字符串拼接问题,经过我的测试验证,单纯的多次创建字符串对象其实根本不是性能差的原因。要命的是在对象创建期间的无谓的垃圾回收的开销。而Array.join的方式,不会创建中间字符串对象,因此就减少了那该死的垃圾回收的开销。
因此,如果我们能把大规模对象创建转化为单一语句,则其性能会得到极大的提高!例如通过构造代码然后eval——实际上PIES项目中正在根据这个想法来做一个专门的大规模对象产生器……
好了上面就是偶总结的JS优化五大原则。
除了这些原则以外,还有一些特殊情况,如DOM的遍历,以后有时间再做讨论。
首先,与其他语言不同,JS的效率很大程度是取决于JS engine的效率。除了引擎实现的优劣外,引擎自己也会为一些特殊的代码模式采取一些优化的策略。例如FF、Opera和Safari的JS引擎,都对字符串的拼接运算(+)做了特别优化。显然,要获得最大效率,就必须要了解引擎的脾气,尽量迎合引擎的口味。所以对于不同的引擎,所作的优化极有可能是背道而驰的。
而如果做跨浏览器的web编程,则最大的问题是在于IE6(JScript 5.6)!因为在不打hotfix的情况下,JScript引擎的垃圾回收的bug,会导致其在真实应用中的performance跟其他浏览器根本不在一个数量级上。因此在这种场合做优化,实际上就是为JScript做优化!
所以第一原则就是只需要为IE6(未打补丁的JScript 5.6或更早版本)做优化!
如果你的程序已经优化到在IE6下可以接受的性能,那基本上在其他浏览器上性能就完全没有问题。
因此,注意我下面讲的许多问题在其他引擎上可能完全不同,例如在循环中进行字符串拼接,通常认为需要用Array.join的方式,但是由于SpiderMonkey等引擎对字符串的“+”运算做了优化,结果使用Array.join的效率反而不如直接用“+”!但是如果考虑IE6,则其他浏览器上的这种效率的差别根本不值一提。
JS优化与其他语言的优化也仍然有相同之处。比如说,不要一上来就急吼吼的做优化,那样毫无意义。优化的关键,仍然是要把精力放在最关键的地方,也就是瓶颈上。一般来说,瓶颈总是出现在大规模循环的地方。这倒不是说循环本身有性能问题,而是循环会迅速放大可能存在的性能问题。
所以第二原则就是以大规模循环体为最主要优化对象。
以下的优化原则,只在大规模循环中才有意义,在循环体之外做此类优化基本上是没有意义的。
目前绝大多数JS引擎都是解释执行的,而解释执行的情况下,在所有操作中,函数调用的效率是较低的。此外,过深的prototype继承链或者多级引用也会降低效率。JScript中,10级引用的开销大体是一次空函数调用开销的1/2。这两者的开销都远远大于简单操作(如四则运算)。
所以第三原则就是尽量避免过多的引用层级和不必要的多次方法调用。
特别要注意的是,有些情况下看似是属性访问,实际上是方法调用。例如所有DOM的属性,实际上都是方法。在遍历一个NodeList的时候,循环条件对于nodes.length的访问,看似属性读取,实际上是等价于函数调用的。而且IE DOM的实现上,childNodes.length每次是要通过内部遍历重新计数的。(My god,但是这是真的!因为我测过,childNodes.length的访问时间与childNodes.length的值成正比!)这非常耗费。所以预先把nodes.length保存到js变量,当然可以提高遍历的性能。
同样是函数调用,用户自定义函数的效率又远远低于语言内建函数,因为后者是对引擎本地方法的包装,而引擎通常是c,c++,java写的。进一步,同样的功能,语言内建构造的开销通常又比内建函数调用要效率高,因为前者在JS代码的parse阶段就可以确定和优化。
所以第四原则就是尽量使用语言本身的构造和内建函数。
这里有一个例子是高性能的String.format方法。String.format传统的实现方式是用String.replace(regex, func),在pattern包含n个占位符(包括重复的)时,自定义函数func就被调用n次。而这个高性能实现中,每次format调用所作的只是一次Array.join然后一次String.replace(regex, string)的操作,两者都是引擎内建方法,而不会有任何自定义函数调用。两次内建方法调用和n次的自定义方法调用,这就是性能上的差别。
同样是内建特性,性能上也还是有差别的。例如在JScript中对于arguments的访问性能就很差,几乎赶上一次函数调用了。因此如果一个可变参数的简单函数成为性能瓶颈的时候,可以将其内部做一些改变,不要访问arguments,而是通过对参数的显式判断来处理。
比如:
代码
function sum() { var r = 0; for (var i = 0; i < arguments.length; i++) { r += arguments[i]; } return r; }
这个sum通常调用的时候个数是较少的,我们希望改进它在参数较少时的性能。如果改成:
代码
function sum() { switch (arguments.length) { case 1: return arguments[0]; case 2: return arguments[0] + arguments[1]; case 3: return arguments[0] + arguments[1] + arguments[2]; case 4: return arguments[0] + arguments[1] + arguments[2] + arguments[3]; default: var r = 0; for (var i = 0; i < arguments.length; i++) { r += arguments[i]; } return r; } }
其实并不会有多少提高,但是如果改成:
代码
function sum(a, b, c, d, e, f, g) { var r = a ? b ? c ? d ? e ? f ? a + b + c + d + e + f : a + b + c + d + e : a + b + c + d : a + b + c : a + b : a : 0; if (g === undefined) return r; for (var i = 6; i < arguments.length; i++) { r += arguments[i]; } return r; }
就会提高很多(至少快1倍)。
最后是第五原则,也往往是真实应用中最重要的性能障碍,那就是尽量减少不必要的对象创建。
本身创建对象是有一定的代价的,但是这个代价其实并不大。最根本的问题是由于JScript愚蠢之极的垃圾回收调度算法,导致随着对象个数的增加,性能严重下降(据微软的人自己说复杂度是O(n^2))。
比如我们常见的字符串拼接问题,经过我的测试验证,单纯的多次创建字符串对象其实根本不是性能差的原因。要命的是在对象创建期间的无谓的垃圾回收的开销。而Array.join的方式,不会创建中间字符串对象,因此就减少了那该死的垃圾回收的开销。
因此,如果我们能把大规模对象创建转化为单一语句,则其性能会得到极大的提高!例如通过构造代码然后eval——实际上PIES项目中正在根据这个想法来做一个专门的大规模对象产生器……
好了上面就是偶总结的JS优化五大原则。
除了这些原则以外,还有一些特殊情况,如DOM的遍历,以后有时间再做讨论。
发表评论
-
转:我为什么向后端工程师推荐NodeJS
2011-09-08 23:10 1383出自http://cnodejs.org,转载请注明出处 ... -
转:Node.js 究竟是什么?
2011-09-05 09:19 1008简介 如果您听说过 ... -
Cache Insight
2011-05-25 17:31 1230http://www.iteye.com/topic/2172 ... -
浅谈javascript面向对象编程
2010-06-23 07:27 1007http://www.ioldfish.cn/?p=238 ... -
Jquery的回车事件
2010-02-07 16:36 1429$('#simpleSearchProjectFilt ... -
Jquery选择器大全
2009-09-27 14:57 7247http://hi.baidu.com/lpk1/blog/i ... -
jquery的extend和fn.extend
2009-07-21 17:33 6815http://hzjavaeyer.group.iteye.c ... -
Jquery each中跳出循环
2009-07-20 17:22 6951continue可以使用return true break可 ... -
Javascript悟透(3)
2009-07-16 14:38 1223当然,这个代码仅仅展示了“语法甘露”的概念。我们还 ... -
Javascript悟透(2)
2009-07-16 14:34 1095但要注意的是,用构造函数操作this对象创建出来的每一 ... -
Javascript悟透
2009-07-16 14:32 1019http://www.cnblogs.com/leadzen/ ... -
Javascript的闭包
2009-07-16 08:52 1087http://www.felixwoo.com/archive ... -
Jquery技巧
2009-06-22 16:38 1019http://jquery.group.iteye.com/g ... -
Asynchronous innerHTML
2009-06-02 10:39 1090A recent question on Stack Over ... -
Fastest way to build an HTML string
2009-06-02 10:28 1153You have a massive array of ite ... -
JS字符串加不同浏览器比较
2009-05-06 09:03 1857function StringBuffer() { ... -
kestrel项目
2009-05-02 01:58 1563kestrel项目,用于MQ,twitter实现 scala语 ... -
Tomcat6安装版本参数修改
2009-04-14 13:41 1518tomcat6w.exe //ES//Tomcat6 -Xr ... -
jquery之dialog的键盘事件
2009-03-10 11:55 1898$('#input_text').keyup(functi ... -
jquery之 each,extend
2009-02-20 11:51 1831$.each(obj, fn):通用的迭代函数。可用于近似地迭 ...
相关推荐
- **原则**: DOM操作通常比JavaScript运算要慢得多。 - **技巧**: 尽量减少直接对DOM的操作次数。例如,可以先将DOM元素缓存到变量中再进行多次操作。 - **示例**: 使用`document.querySelector`或`document....
JavaScript性能优化是提升网页加载速度和用户交互体验的关键。以下是一些实用的JS优化技巧: ...遵循这些优化原则,可以有效地提升JavaScript代码的执行效率,从而加快网页加载速度,提升用户体验。
在IT行业中,优化JavaScript(JS)和CSS代码对于提高网页性能和用户体验至关重要。...尽管现在有更多先进的工具(如Webpack、Babel、Prettier等),但理解这些基本优化原则仍然是每个前端开发者必备的技能。
【JS特效-3D翻转导航】是一种利用JavaScript和HTML5技术实现的创新网页导航设计。这个特效将传统的导航栏转换为具有3D视觉效果的交互式元素,为用户带来更丰富的浏览体验。通过3D翻转,菜单项在用户交互时会呈现出...
网站优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议。雅虎的工程师团队曾经给出过 35 个最佳实践,可以参照Best Practices for Speeding Up Your Web Site。同时,他们还发布了一个相应的...
- 在代码的后期维护和优化阶段,可以考虑重构以遵循单一职责原则。 其次,**开放封闭原则**(Open-Closed Principle, OCP)主张已定义的对象或函数应允许扩展,但禁止修改。其核心思想是通过增加新代码来扩展功能,...
在IT领域,JavaScript(简称JS)是一种广泛应用于网页和网络应用开发的编程语言,尤其在交互性方面表现突出。在给定的“JS图片查看器(缩放/旋转/翻转)兼容性强.rar”压缩包中,我们关注的是一个利用JavaScript实现的...
Vue.js 是一款非常流行的前端JavaScript框架,以其轻量级、易学易用和高性能的特点深受开发者喜爱。在项目开发过程中,优化Vue.js的结构对于提高应用性能和减少资源占用至关重要。"vue_vue_"这个标题可能指的是针对...
JavaScript代码优化是一项持续且重要的工作,它有助于提高代码的执行效率、可读性和可维护性。...随着现代JavaScript框架和构建工具的发展,遵循这些优化原则变得更加容易,开发者应当在实践中积极应用这些知识。
--形成关键词分析报告及布署方案 搜索引擎友好化---撰写站点修改措施建议书 内容强化---资讯频道建立、对编辑团队的培训 内部优化---URL优化、各级页面DIV重构、关键字布局、目录逻辑结构调整、JS优化、专题页建设等...
"web+笔试+面试汇总+前端优化总结+js+css"的主题涵盖了前端开发中的关键领域,包括ECMAScript语法、HTML表格与表单处理、浏览器对象模型(BOM)、事件处理以及前端优化策略。 ECMAScript是JavaScript的标准化规范,...
综上所述,提高JavaScript的性能,关键在于理解其代码的执行机制,以及合理利用各种JavaScript引擎提供的优化技术。开发者应该在整个开发周期中持续关注性能问题,采用合适的工具和方法来诊断和解决性能瓶颈,并且...
这个名为"js.rar_javascript_js_js 农历_lunar"的压缩包包含了一个专门处理中国农历的JavaScript实例。在这个实例中,开发者仅用了一个文件就实现了农历的计算和展示功能,展现了JavaScript的强大灵活性和高效性。 ...
Chrome V8引擎中的JavaScript数组实现分析与性能优化 在本文中,我们将对Chrome V8引擎中的JavaScript数组实现进行深入分析,并探讨如何通过优化JavaScript数组的使用方式来提高程序效率。在实际应用中,JavaScript...
"基于CSS和JavaScript的网页选项卡的设计和优化" 根据提供的文件信息,我们可以...基于CSS和JavaScript的网页选项卡的设计和优化需要遵循设计原则,简短、精炼、整体性等,才能使选项卡在实际应用中发挥最佳的效果。
它的设计原则是简洁、直观,使得页面在微信内置浏览器中运行时,能保持与微信自身界面的一致性,提升用户的使用感受。 4. **JavaScript 开发语言**: JavaScript 是一种广泛应用于网页和网络应用的脚本语言,它在...
这个文件是MUI框架的完整源代码,包含了所有未经过压缩和优化的JavaScript代码。开发者在开发阶段通常会使用这个版本,因为其中包含了详细的注释和调试信息,方便在开发过程中进行问题排查和功能调试。MUI.js提供了...
JS(JavaScript)作为一种强大的客户端脚本语言,被广泛用于实现动态和交互性的下拉菜单效果。以下是对“19款比较酷的js下拉菜单效果”这一主题的详细解析: 1. **响应式设计**:现代网页设计强调响应式,这些js...