码迷,mamicode.com
首页 > Web开发 > 详细

Js极客之路 - 优化操作(性能优化)

时间:2015-07-03 18:48:44      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:

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://web.jobbole.com/82381/

  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

 

--继续进步,继续添加

--分享知识,铸就大我,等你指导

 

Js极客之路 - 优化操作(性能优化)

标签:

原文地址:http://www.cnblogs.com/aiweidong/p/4619153.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!