Home  >  Article  >  Web Front-end  >  About how to optimize your JS code (graphic tutorial)

About how to optimize your JS code (graphic tutorial)

亚连
亚连Original
2018-05-18 15:39:541465browse

The execution efficiency of JS code often directly affects the performance of the page. Sometimes, different JS codes often have a lot of difference in efficiency to achieve the same function. Sometimes it is just due to our writing habits. Of course In advanced browsers, most of them have helped us optimize it, but in China, the evil IE6 still exists in large numbers, and we have to consider it. Regarding the optimization of JS code, there are actually many situations, some of which have a relatively small impact, and some of which are more serious. In this article, I list a few situations that I think have a serious impact for your reference.

1. String splicing

String splicing is often encountered in our development, so I put it first. We are often used to splicing directly using =. Strings, in fact, this method of splicing is very inefficient. We can use a clever method to splice strings, which is to use the join method of the array.

<p class="one" id="one"></p>   
<input type="button" value="效率低" onclick="func1()" />   
<input type="button" value="效率高" onclick="func2()" /> //效率低的   function func1(){   
    var start = new Date().getTime();   
    var template = "";   
    for(var i = 0; i < 10000; i++){   
        template += "<input type=&#39;button&#39; value=&#39;a&#39;>";   
    }   
    var end = new Date().getTime();   
    document.getElementById("one").innerHTML = template;   
    alert("用时:" + (end - start) + "毫秒");   }   //效率高的   function func2(){   
    var start = new Date().getTime();   
    var array = [];   
    for(var i = 0; i < 10000; i++){   
        array[i] = "<input type=&#39;button&#39; value=&#39;a&#39;>";   
    }   
    var end = new Date().getTime();   
    document.getElementById("one").innerHTML = array.join("");   
    alert("用时:" + (end - start) + "毫秒");   }

Let’s take a look at its execution under different browsers

About how to optimize your JS code (graphic tutorial)

We will find that the difference under IE6 is quite obvious. In fact, this This situation is also very obvious in higher versions of IE, but there is not much difference under Firefox. On the contrary, the relative efficiency of the second type is even lower, but the difference is only about 2ms, and Chrome is similar to Firefox. In addition, by the way, when we add elements to the array, many people like to use the native method of push. In fact, it is faster to directly use arr[i] or arr[arr.length], which is about 10000. In the case of multiple loops, there will be a difference of more than ten milliseconds under IE browser.

2. for loop

The for loop is a situation we often encounter. Let’s take a look at the following example:

<input type="button" value="效率低" onclick="func1()" />   
<input type="button" value="效率高" onclick="func2()" /> 
var arr = [];   
for(var i = 0; i < 10000; i++){   
    arr[i] = "<p>" + i + "</p>";   
}   
document.body.innerHTML += arr.join("");   
//效率低的   function func1(){   
    var ps = document.getElementsByTagName("p");   
    var start = new Date().getTime();   
    for(var i = 0; i < ps.length; i++){   
        //"效率低"   
    }   
    var end = new Date().getTime();   
    alert("用时:" + (end - start) + "毫秒");   
}   
//效率高的   function func2(){   
    var ps = document.getElementsByTagName("p");   
    var start = new Date().getTime();   
    for(var i = 0, len = ps.length; i < len; i++){   
        //"效率高"   
    }   
    var end = new Date().getTime();   
    alert("用时:" + (end - start) + "毫秒");   
}

About how to optimize your JS code (graphic tutorial)

As can be seen from the above table, the difference is very obvious under IE6.0, while there is almost no difference under Firefox and Chrome. The reason why this happens under IE6.0 is mainly because the for loop is executing , the first case will calculate the length every time, but the second case will calculate the length at the beginning and save it to a variable, so its execution efficiency is higher, so when we use a for loop , especially if we need to calculate the length, we should start saving it into a variable. But there will not be such an obvious difference as long as the length is obtained. If we only operate an array and obtain the length of an array, then the two methods of writing are actually similar. Let’s look at the following example:

<input type="button" value="效率低" onclick="func1()" />   
<input type="button" value="效率高" onclick="func2()" />  
var arr2 = [];   
for(var i = 0; i < 10000; i++){   
    arr2[i] = "<p>" + i + "</p>";   
}   
//效率低的   function func1(){   
    var start = new Date().getTime();   
    for(var i = 0; i < arr2.length; i++){   
        //"效率低"   
    }   
    var end = new Date().getTime();   
    alert("用时:" + (end - start) + "毫秒");   
}   
//效率高的   function func2(){   
    var start = new Date().getTime();   
    for(var i = 0, len = arr2.length; i < len; i++){   
        //"效率高"   
    }   
    var end = new Date().getTime();   
    alert("用时:" + (end - start) + "毫秒");   
}

About how to optimize your JS code (graphic tutorial)

As can be seen from the above table, if it is just an array, we can see that the two writing methods are almost the same. In fact, if we increase the loop to 100,000 times, The difference is only a few milliseconds, so in the case of arrays, I think they are the same. Regarding the optimization of the for loop, some people have also put forward many points. Some people think that using -=1, or looping from large to small, etc., I think it is completely unnecessary. These optimizations are often not reflected at all in actual situations. Change In a word, it is only a small change at the computer level, but what it brings us is that the readability of the code is greatly reduced, so it is really not worth the loss.

3. Reduce page redrawing

Reducing page redrawing is not essentially an optimization of JS itself, but it is often caused by JS, and redrawing often seriously affects the page. Performance, so it is completely necessary to take it out. Let’s look at the following example:

<p id="demo"></p>   
<input type="button" value="效率低" onclick="func1()" />   
<input type="button" value="效率高" onclick="func2()" /> 
var str = "<p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p><p>这是一个测试字符串</p>";   
//效率低的   function func1(){   
    var obj = document.getElementById("demo");   
    var start = new Date().getTime();   
    for(var i = 0; i < 100; i++){   
        obj.innerHTML += str + i;   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");   
}   
//效率高的   function func2(){   
    var obj = document.getElementById("demo");   
    var start = new Date().getTime();   
    var arr = [];   
    for(var i = 0; i < 100; i++){   
        arr[i] = str + i;   
    }   
    obj.innerHTML = arr.join("");   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");

About how to optimize your JS code (graphic tutorial)

What you can see is that this is simply an amazing result, just 100 times of looping , no matter what browser it is under, there is such a big difference. In addition, we also found that here, the execution efficiency of IE6 is actually much better than that of Firefox. It can be seen that Firefox has not done anything in terms of page redrawing. Optimization. It should also be noted here that it is not just innerHTML that generally affects page redrawing. Changing the style, position, etc. of elements will trigger page redrawing, so you must pay attention to this in normal times.

4. Reduce the number of searches on the scope chain
We know that when js code is executed, if it needs to access a variable or a function, it needs to traverse the scope chain of the current execution environment , and traversal is to traverse backward from the front end of this scope chain level by level until the global execution environment, so there will often be a situation here, that is, if we need to frequently access the variable objects of the global environment, we will Each time, the current scope chain must be traversed level by level, which is obviously time-consuming. Let’s look at the following example:

<p id="demo"></p>   
<input id="but1" type="button" onclick="func1()" value="效率低"/>   
<input id="but2" type="button" onclick="func2()" value="效率高"/>   
function func1(){   
    var start = new Date().getTime();   
    for(var i = 0; i < 10000; i++){   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
        var but1 = document.getElementById("but1");   
        var but2 = document.getElementById("but2");   
        var inputs = document.getElementsByTagName("input");   
        var ps = document.getElementsByTagName("p");   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");   
}   
function func2(){   
    var start = new Date().getTime();   
    var doc = document;   
    for(var i = 0; i < 10000; i++){   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
        var but1 = doc.getElementById("but1");   
        var but2 = doc.getElementById("but2");   
        var inputs = doc.getElementsByTagName("input");   
        var ps = doc.getElementsByTagName("p");   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");

上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了,所以我们看看其执行结果: 

About how to optimize your JS code (graphic tutorial)

从上表中可以看出,其在IE6下差别还是非常明显的,而且这种差别在多级作用域链和多个全局变量的情况下还会表现的非常明显。

5、避免双重解释

双重解释的情况也是我们经常会碰到的,有的时候我们没怎么考虑到这种情况会影响到效率,双重解释一般在我们使用eval、new Function和setTimeout等情况下会遇到,我们看看下面的例子:

<p id="demo"></p>   
<input id="but1" type="button" onclick="func1()" value="效率低"/>   
<input id="but2" type="button" onclick="func2()" value="效率高"/>   
var sum, num1 = 1, num2 = 2;   
function func1(){   
    var start = new Date().getTime();   
    for(var i = 0; i < 10000; i++){   
        var func = new Function("sum+=num1;num1+=num2;num2++;");   
        func();   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");   
}   
function func2(){   
    var start = new Date().getTime();   
    for(var i = 0; i < 10000; i++){   
        sum+=num1;   
        num1+=num2;   
        num2++;   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");   
}

第一种情况我们是使用了new Function来进行双重解释,而第二种是避免了双重解释,我们看看在不同浏览器下的表现: 

 About how to optimize your JS code (graphic tutorial)

可以看到,在所有的浏览器中,双重解释都是有很大开销的,所以在实际当中要尽量避免双重解释。

感谢”SeaSunK”对第四点测试报告错误的指正,现在已经修改过来了。至于最后一点提出的func1每次都初始化,没有可比性,所以我给换了eval,结果发现,在IE6.0下还是有影响,而且在Firefox下,使用eval对效率的影响程度更加厉害,在Firefox下,如果10000次循环,需要十多秒的时间,所以我把循环都变成了1000次。看代码和报告。

var sum, num1 = 1, num2 = 2;   
function func1(){   
    var start = new Date().getTime();   
    for(var i = 0; i < 1000; i++){   
        eval("sum+=num1;num1+=num2;num2++;");   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");   
}   
function func2(){   
    var start = new Date().getTime();   
    for(var i = 0; i < 1000; i++){   
        sum+=num1;   
        num1+=num2;   
        num2++;   
    }   
    var end = new Date().getTime();   
    alert("用时 " + (end - start) + " 毫秒");

About how to optimize your JS code (graphic tutorial)

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

JavaScript设计模式系列一:工厂模式

JavaScript设计模式系列二:单例模式

JavaScript设计模式系列三:建造者模式

The above is the detailed content of About how to optimize your JS code (graphic tutorial). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn