1.因为每次For循环都会计算一次arr.length,所以有必要存储数组长度以减少计算。针对这篇文章(http://www.crimx.com/2015/04/21/should-array-length-be-cached-or-not/),V8引擎好像已经帮我们做了不变数据的缓存,不过个人认为还是很有必要的,像他说的,假若只有V8引擎做了此事(V8开发者有这样说吗?),我们做缓存,对于V8就当帮它咯,对于其他就是优化咯。
//bad var arr=[1,2,3,...]; for(var i=0; i<arr.length; i++){ ...code } //good var arr=[1,2,3,...], len=arr.length, i=0; for(; i<len; i++){ ...code }
2.将字符串转变成数字的几种方法。
//第一种: var a=‘12‘; console.log(typeof a); //string a=parseInt(a); //parseInt()、Math.floor()等 console.log(typeof a); //number //第二种: var a=‘12‘; a=a-0; //-、*、/等 console.log(typeof a); //number //第三种(参考地址-http://www.w3school.com.cn/js/pro_js_operators_unary.asp): var a=‘12‘; a = +a ; //+、-、~等 console.log(typeof a); //number //第四种: var a=‘12‘; a = a >> 0 ; //>>、>>>等 console.log(typeof a); //number 听说第二种和第三种是性能快点,或许可以参照《将数字转变成字符串的几种方法》下别人的话。 第四种计算过程参考: ①:https://msdn.microsoft.com/zh-cn/library/5s9e947e(v=vs.94).aspx ②:http://zhidao.baidu.com/link?url=lHM_2XsAX2N3zmaDwhA8IUivdkjhBO-9RLYg-qLRfTuh7qo2wJYaEZXi5mlu4VWPMSNtBL404448uJBxrrfK_Y-E4WDdhSgg31ofHAj72nC
3.将数字转变成字符串的几种方法。
//第一种: var a=100; console.log(typeof a); //number a=a.toString(); //toString()、toFixed()等 console.log(typeof a); //string //第二种: var a=100; a=‘‘+a; console.log(typeof a); //string 别人的话:从性能上来看,将数字转换成字符时,有如下公式:("" +) > String() > .toString() > new String()。String()属于内部函数,所以速度很快。而.toString()要查询原型中的函数,所以速度逊色一些,new String()需要重新创建一个字符串对象,速度最慢。
4.选择作用域链最短的方法:Javascript的变量采用链式作用域;读取变量的时候,先在当前作用域寻找该变量,如果找不到,就前往上一层的作用域寻找该变量;这样的设计,使得读取局部变量比读取全局变量快得多。
//bad,假设num只在a函数里被使用 var num=10; function a(){ num++; ...code } a(); //good function a(){ var num=10; num++; ...code } a();
5.多个if-else执行的时候,其会顺序检索每一个条件,直到所有条件检索完或检索到匹配的条件,所以我们可以通过树的形式组织if语句(正常人应该不会这样做)。
//bad? if(con === 1) {return result1;} else if(con === 2) {return result2;} else if(con === 3) {return result3;} else if(con === 4) {return result4;} else if(con === 5) {return result5;} else if(con === 6) {return result6;} else if(con === 7) {return result7;} else if(con === 8) {return result8;} else if(con === 9) {return result9;} 这段代码就会依次判断con是否等于1,2,3,4,5,6,7,8,9,如果是9的话,就会判断9次。 //good? if (con <= 3){ if(con === 1) {return result1;} else if(con === 2) {return result2;} else {return result3;} } else if(con > 3 && con <= 6){ if(con === 4) {return result4;} else if(con === 5) {return result5;} else {return result6;} } else if(con <= 9){ if(con === 7) {return result7;} else if(con === 8) {return result8;} else {return result9;} } 这样我们通过三叉树的形式,就可以减少查找次数了,比如这里查找9次,分别判断 0~3,3~6,6~9,7,8,9,只需要6次。 if-else除了通过这种树形组织编码以外,还有一个优化的地方。由于其顺序判断的逻辑,我们可以根据概率来,将概率比较大的判断放在前面,概率较小的放在后面,这样也可以减少平均查找长度(这个才是人可以做的)。
6.ECMAScript 5方法的使用。
ES5提供了很多新的方法,虽然老式的浏览器不支持,但现在都是HTML5时代了,所以能用ES5的方法的时候就大胆的用;有句话好像说的好:浏览器自带的方法怎么都比你用js写出来的方法高效,因为它用的更加底层的语言写的。
DOM优化:
1.使用DocumentFragment优化多次append?
也许对于老的浏览器有效(http://ejohn.org/blog/dom-documentfragments/),但是现代浏览器都优化的很好了,所以此方式已显得不为重要,过时(http://www.zhihu.com/question/30498056#answer-14749261)。
2.使用一次innerHTML赋值代替多次向DOM结构里添加新节点,减少DOM与JS的交互。
//bad for(var i=0; i<1000; i++){ var elem=document.createElement(‘p‘); elem.innerHTML=i; document.body.appendChild( elem ); } //good var html=[], i=0; for(; i<1000; i++){ html.push( ‘<p>‘+i+‘</p>‘ ) } document.body.innerHTML+=html.join(‘‘);
3.减少回流或重绘(http://www.css88.com/archives/4996)。
▊ 使用更改className的方式替换style.xxx=xxx的方式。
▊ 使用style.cssText = ‘‘;一次写入样式。
//bad var oDiv=document.getElementById(‘test‘); oDiv.onclick=function(){ this.style.background=‘red‘; this.style.fontSize=‘12px‘; this.style.border=‘1px solid #ccc‘; } //good var oDiv=document.getElementById(‘test‘); oDiv.onclick=function(){ this.className=‘xxx‘ } 或者 oDiv.onclick=function(){ this.style.cssText=‘background: red; font-size: 12px; border: 1px solid #ccc;‘ }
4.使用事件委托的方式替代给每个元素添加事件,既可以减少子元素的事件绑定,动态添加的元素又相当于获得了相应的事件。
例:页面有一个div(id="wrap"),div下面有100个span,现在需求是点击每个span,弹出span里的文本内容。 //bad var aSpan=document.getElementById(‘wrap‘).getElementsByTagName(‘span‘), len=aSpan.length, i=0; for(; i<len; i++){ aSpan[i].onclick=function(){ alert( this.textContent ) } } //good document.getElementById(‘wrap‘).onclick=function(e){ alert( e.target.textContent ) }
SVG优化:
1.给组添加样式替代给多个子元素添加样式(引:这是一种无损优化,既可以减少文件大小又可以提高渲染速度)。
//bad <rect width="20" height="20" fill="#F15C80" ></rect> <circle cx="40" cy="10" r="10" fill="#F15C80" ></circle> ...more //good <g fill="#F15C80"> <rect width="20" height="20" ></rect> <circle cx="40" cy="10" r="10" ></circle> ...more </g>
2.缩小精度(引:过度的准确性常见于自动生成的SVG文件中,缩放小数精度的优化效果是显而易见的,但是除去1位小数是对于文件而言是没有太大区别的。这是一个有损耗的方法来减少文件大小,加快加载速度),这个对于画图其实是有必要的,计算值往往小数位很多,而实际为了让图形显示得不模糊,我们会取整后±0.5。
//bad <path d="M165.381249999999994 -.5v400" stroke="#90ED7D" stroke-width="1.2"></path> //good <path d="M165.5 -.5v400" stroke="#90ED7D" stroke-width="1.2"></path>
3.创建SVG DOM元素时先设置其样式,再将其添加到父级。因为FF(开发者版本好像可以),IE不支持innerHTML添加的SVG DOM元素,所以只能用appendChild添加,此时先设置样式可以减少回流或重绘。
//bad var oRect=document.createElementNS(‘http://www.w3.org/2000/svg‘,‘rect‘); oSvg.appendChild(oRect); oRect.setAttribute(‘width‘,30); oRect.setAttribute(‘height‘,30); //good var oRect=document.createElementNS(‘http://www.w3.org/2000/svg‘,‘rect‘); oRect.setAttribute(‘width‘,30); oRect.setAttribute(‘height‘,30); oSvg.appendChild(oRect);
jQuery优化:
1.缓存重复使用的jQuery对象减少查询。
//bad var oP=$(‘#test‘).find(‘p‘), oEm=$(‘#test‘).find(‘em‘); //good var oBox=$(‘#test‘), oP=oBox.find(‘p‘), oEm=oBox.find(‘em‘);
2.jQuery最佳实践:http://www.ruanyifeng.com/blog/2011/08/jquery_best_practices.html
逻辑优化:
1.函数节流,减少事件交互次数(学习地址->http://www.alloyteam.com/2012/11/javascript-throttle/)。
2.单例模式(学习地址->http://www.alloyteam.com/2012/10/common-javascript-design-patterns/)。
3.具体场景具体分析。
性能优化总结:
以上内容基本是经过测试,或者说得很有道理(不知道该怎么测试),期待指正,教导。
性能优化,对于一些小程序或者高配置来说几乎用肉眼是感受不到的,但是对于大数据可视化、低配置、热爱极致完美的人来说,优化还是非常必要的,Perfect的感觉非“强迫症”的人不懂!
对于类似A && B || C 与 A ? B : C 谁的效率更高这样的问题,做为正常人就引用一句话吧(原文地址->http://www.zhihu.com/question/20293486):
不同的浏览器解析方式未必相同,所以:适合自己的才是最好的。
参考:
http://www.codeceo.com/article/javascript-guide.html
http://www.csdn.net/article/2015-01-27/2823722
http://segmentfault.com/a/1190000000490326#articleHeader31
其他资源
相关阅读:
http://segmentfault.com/a/1190000000490324
http://blog.csdn.net/lfsf802/article/details/40628453
--继续进步,继续添加
--分享知识,铸就大我,等你指导