Javascript is a very flexible language. We can write various styles of code as we like. Different styles of code will inevitably lead to differences in execution efficiency. During the development process, we are exposed to many methods to improve code performance. Let's sort out the common and easy to avoid problems.
Javascript's own execution efficiency
The scope chain, closure, prototype inheritance, eval and other features in Javascript provide various magical functions while also bringing various efficiency problems. If you use it carelessly, you will lead to inefficient execution.
1. Global import
We will use some global variables (window, document, custom global variables, etc.) during the encoding process. Anyone who knows the JavaScript scope chain knows that accessing global variables in a local scope requires traversing the entire scope chain layer by layer until the top-level scope, and the access efficiency of local variables will be faster and higher. Therefore, when using some global objects at high frequency in the local scope, it can be imported into the local scope, for example:
The code copy is as follows:
//1. Pass it into the module as a parameter
(function(window,$){
var xxx = window.xxx;
$("#xxx1").xxx();
$("#xxx2").xxx();
})(window,jQuery);
//2. Storing to local variables
function(){
var doc = document;
var global = window.global;
}
2. Eval and class eval problems
We all know that eval can use a string as js code to execute and process it. It is said that the code executed using eval is more than 100 times slower than the code not using eval (I have not tested the specific efficiency, and those who are interested can test it)
JavaScript code will perform similar "precompilation" operations before execution: first, it will create an active object in the current execution environment, and set the variables declared with var as properties of the active object, but at this time the assignments of these variables are undefined, and functions defined in function are also added as properties of the active object, and their values are exactly the definition of the function. However, if you use "eval", the code in "eval" (actually a string) cannot pre-identify its context, cannot be parsed and optimized in advance, i.e. pre-compiled operations cannot be performed. Therefore, its performance will be greatly reduced
In fact, people rarely use eval now. What I want to talk about here is a scenario of two types of eval (new Function{}, setTimeout, setInterver)
The code copy is as follows:
setTimtout("alert(1)",1000);
setInterver("alert(1)",1000);
(new Function("alert(1)"))();
The above types of code execution efficiency will be relatively low, so it is recommended to directly pass anonymous methods or references to the setTimeout method.
3. After the closure is finished, the variable that is no longer referenced will be released.
The code copy is as follows:
var f = (function(){
var a = {name:"var3"};
var b = ["var1","var2"];
var c = document.getElementByTagName("li");
//****Other variables
//***Some operations
var res = function(){
alert(a.name);
}
return res;
})()
The return value of the variable f in the above code is a method res returned in a closure composed of an immediate execution function. This variable retains references to all variables (a, b, c, etc.) in this closure. Therefore, these two variables will always reside in the memory space, especially the reference to the dom element will consume a lot of memory. We only use the value of the variable a in res. Therefore, we can free other variables before the closure returns.
The code copy is as follows:
var f = (function(){
var a = {name:"var3"};
var b = ["var1","var2"];
var c = document.getElementByTagName("li");
//****Other variables
//***Some operations
//Release the variables that are no longer used before the closure returns
b = c = null;
var res = function(){
alert(a.name);
}
return res;
})()
The efficiency of Js operating dom
During the web development process, the bottleneck of front-end execution efficiency is often on dom operations. DOM operations are a very performance-consuming thing. How can we try to save performance during DOM operations?
1. Reduce reflow
What is reflow?
When the properties of the DOM element change (such as color), the browser will notify the render to redefine the corresponding element. This process is called repaint.
If the change involves the element layout (such as width), the browser discards the original attributes, recalculates and passes the result to the render to redelineate the page elements. This process is called reflow.
How to reduce reflow
First delete the element from the document, and after completing the modification, then put the element back to its original position (when a large number of reflow operations are performed on a certain element and its child elements, the effects of the 1 and 2 methods will be more obvious)
Set the display of the element to "none", and after completing the modification, modify the display to the original value
Define the class class when modifying multiple style attributes instead of modifying the style attributes multiple times (recommended by certain students)
Use documentFragment when adding large amounts of elements to the page
For example
The code copy is as follows:
for(var i=0;i<100:i++){
var child = docuemnt.createElement("li");
child.innerHtml = "child";
document.getElementById("parent").appendChild(child);
}
When the code requires multiple access to the state information of an element, we can temporarily store it in a variable when the state remains unchanged, which can avoid the memory overhead caused by multiple access to the dom. A typical example is:
When searching for dom elements, try to avoid traversing page elements in large areas, try to use accurate selectors, or specify a context to narrow the search range, taking jquery as an example
Use less fuzzy matching selectors: for example $("[name*='_fix']"), more use more composite selectors such as id and gradually narrowing the scope $("li.active"), etc.
Specify the context: for example $("#parent .class"), $(".class", $el) and so on
4. Use event delegation
Usage scenario: A list with a large number of records. Each record needs to be bound to click events. Some functions are implemented after clicking on the mouse. Our usual practice is to bind to listen events for each record. This practice will lead to a large number of event listeners on the page, which is relatively inefficient.
Basic principle: We all know that events will bubble in the dom specification, that is, events of any element will bubble to the top step by step according to the structure of the dom tree. Event object also provides event.target (srcElement under IE) to point to the event source, so we can find the most original element that triggers the event even if we listen to the event on the parent element. This is the basic principle of delegate. Without further ado, the above example
Based on the principle of monitoring events introduced above, let's rewrite it.
Of course, we don’t have to judge the event source every time, we can abstract it and hand it over to the tool class to complete it. The delegate() method in jquery implements this function
The syntax is like $(selector).delegate(childSelector, event,data,function), for example:
The code copy is as follows:
$("div").delegate("button","click",function(){
$("p").slideToggle();
});
Parameter description (quoted from w3school)
Parameter description
childSelector is required. Specifies that one or more child elements of the event handler to be attached.
Event is required. Specifies one or more events attached to the element. Separate multiple event values by spaces. Must be a valid event.
data is optional. Specifies the additional data passed to the function.
function required. Specifies the function that runs when an event occurs.
Tips: Another advantage of event delegation is that even events triggered on elements dynamically added after event binding can be heard, so that you don’t have to bind events to each time you dynamically add an element to the page.