JavaScript Suggestions for improving website performance optimization of II

  • 2021-07-04 18:19:50
  • OfStack

In javascript's suggestions on improving website performance (1), some suggestions are put forward from HTTP request to page rendering. After learning another book of Steve Sounders, "Advanced Guide to High Performance Website Construction", this paper summarizes from the perspective of JavaScript performance.

JavaScript performance is the key to implementing high-performance Web applications

--Steve Sounders

1 Using js scope chain

Scope chain (scope chain)

When executing a piece of JavaScript code (global code or function), the JavaScript engine will create a scope, also known as execution context (Execution Context). After the page is loaded, a global scope will be created first, and then a corresponding scope will be established for every function executed, thus forming a scope chain. Each scope has a corresponding scope chain, with the global scope at the beginning and the current function scope at the end.

The scope chain is used to parse identifiers, When a function is created (not executed), this, arguments, named parameters, and all local variables in the function are added to the current scope, When JavaScript needs to find the variable X (this process is called variable resolution), It first looks for the X attribute from the end of the scope chain, which is the current scope. If it is not found, continue to search along the scope chain until the chain head, that is, the global scope chain, is found, and the variable is still not found, then the x variable does not exist in the scope chain of this code, and an exception of reference error (ReferenceError) is thrown.

Managing the depth of the scope chain is an easy way to improve performance with a small amount of work, and we should avoid inadvertently increasing the scope chain and causing slow execution.

Use local variables (minimize the scope chain)

If we understand the concept of scope chain, we should be clear that the parsing time of variables by JavaScript engine is related to the depth of scope chain. Obviously, local variables have the fastest access speed because they are at the end of the chain. Therefore, a good experience is: When any non-local variables are used more than once, please use local variables to store them, for example:


function changeDiv(){
document.getELementById('myDiv').className = 'changed';
document.getELementById('myDiv').style.height = 150;
}

Here, myDiv, the dom element, is referenced twice. For faster reference, we should store it with a local variable. The advantage of this is not only to shorten the scope chain, but also to avoid repeated queries of DOM elements:


function changeDiv(){
var myDivStyle = document.getElementById('myDiv').style;
myDiv.className = 300;
myDiv.style.height = 150;
}

Avoid using with (do not grow the scope chain)

1 In general, the scope chain of a function is fixed during code execution, whereas with can temporarily increase the scope chain of a function. with is used to display object properties as local variables for easy access, such as:


var user = {
name:'vicfeel',
age:'23'
};
function showUser(){
var local = 0;
with(user){
console.log(" Name " + name);
console.log(" Age " + age);
console.log(local);
}
}
showUser();

In this example, through with, a temporary scope is added to the tail of showUser scope chain, which stores all attributes of user objects, that is, the scope chain of with code is added. In this code, local variables like local change from the first object at the tail to the second, which naturally slows down the access of identifiers. Until the with statement ends, the scope chain resumes growing. Because of this flaw in with, we should try to avoid using the with keyword.

2 More reasonable flow control

Like other programming languages, JavaScript has some flow control statements (loops, conditions, etc.). Using appropriate statements in each link can greatly improve the running speed of scripts.

Fast condition judgment

When it comes to condition judgment, one of the first ways to avoid:


if(value == 0){
return result0;
}
else if(value == 1){
return result1;
}
else if(value == 2){
return result2;
}
else if(value == 3){
return result3;
}
else if(value == 4){
return result4;
}
else if(value == 5){
return result5;
}
else if(value == 6){
return result6;
}
else{
return result7;
}

The main problem with this method of using if for conditional judgment is that it is too deep. When I want value = 7, it takes much longer than value = 0, which greatly consumes performance and is poor readability.

A better way to judge is to use switch.


swithc(value){
case 0:
return result0;
case 1:
return result1;
case 2:
return result2;
case 3:
return result3;
case 4:
return result4;
case 5:
return result5;
case 6:
return result6;
default:
return result7;
}

This not only improves readability, but also makes the query time faster than if. But if is faster than switch if there are only 1 or 2 conditions

In JavaScript, there is another way of conditional query. The previous example is to return different values according to values, which can just use arrays to realize the mapping query of hash tables.


// Defining Array 
var results = [result0,result1,result2,result3,result4,result5,result6,result7];
// Query results 
return results[value];

This array method is more effective when the query scope is large, because it does not need to detect the upper and lower boundaries, but only needs to fill in the index value to query. Its limitation is that the condition corresponds to a single 1 value, not a series of 1 operations. Therefore, it is necessary to integrate the actual situation, choose the appropriate condition judgment mode, and maximize the performance.

Rapid circulation

There are four types of JavaScript cycles: for cycle, do-while cycle, while cycle and for-in cycle. Here is a common way to recycle:


var values = [1,2,3,4,5];
for(var i = 0;i < values.length;i++){
process(values[i]);
}

We can see that the most obvious optimization of this code lies in values. length. Each loop of i has to be compared with the length of values, and querying attributes takes more time than local variables. If the number of loops is larger, the more obvious this time consumption is, so it can be optimized as follows:


var values = [1,2,3,4,5];
var length = values.length;// Local variable storage array length 
for(var i = 0;i < length;i++){
process(values[i]);
}

This code can also continue to be optimized, decrementing the loop variable to 0 instead of adding it to the total length.


var values = [1,2,3,4,5];
var length = values.length;
for(var i = length;i--;){ // Decrease to 0
process(values[i]);
}

Here, the end of the loop is changed to 0, so the speed of each loop is faster. Depending on the complexity of the loop, this simple change can save about 50% of the time.


Related articles: