Summary of little knowledge about JavaScript performance optimization, and javascript Performance Optimization

Source: Internet
Author: User
Tags javascript array

Summary of little knowledge about JavaScript performance optimization, and javascript Performance Optimization

With the development of the network, network speed and machine speed, more and more websites use a variety of client technologies. Ajax is currently the most popular method. JavaScript is an interpreted language, so it cannot reach the level of C/Java, which limits what it can do on the client. In order to improve its performance, I want to talk about my experience based on the many tests I have done for JavaScript before, hoping to help you improve your JavaScript script performance.

Preface

I have been learning javascript, and I have also read "detailed explanation and practice of sharply developing the Jquery kernel". I only have two sharp comments on this book, it may be because the understanding of javascript is not thorough enough, or you are too stupid. More importantly, you are not good at thinking, so you are too lazy to think about it, so that you do not have a deep understanding of the essence.

In view of the fact that you want to improve yourself and cannot enter a broader world, you have to find your own home to survive. Therefore, you will accumulate some common knowledge about using jQuerry intentionally or unintentionally, especially for the performance requirement, I always want to see if there is a better way to achieve it.

Below are some tips I have summarized for your reference only. (I will first talk about a general title, and then use a short paragraph to describe this meaning, and finally use a demo to briefly describe it)

Avoid global search

In a function, Global Object Storage is used as a local variable to reduce global search, because accessing local variables is faster than accessing global variables.

Function search () {// when I want to use the current page address and host Domain Name alert (window. location. href + window. location. host);} // The best way is to use a simple variable to save function search () {var location = window. location; alert (location. href + location. host );}

Timer

SetTimeout should not be used for continuously running code, but setInterval, because setTimeout initializes a timer each time, and setInterval only initializes one timer at the beginning.

Var timeoutTimes = 0; function timeout () {timeoutTimes ++; if (timeoutTimes <10) {setTimeout (timeout, 10) ;}} timeout (); // you can replace it: var intervalTimes = 0; function interval () {intervalTimes ++; if (intervalTimes >=10) {clearInterval (interv) ;}} var interv = setInterval (interval, 10 );

String connection

To connect multiple strings, use less + =, as shown in figure

s+=a;s+=b;s+=c;

It should be written as s + = a + B + c;

If it is a collection string, for example, multiple + = operations on the same string, it is best to use a cache, use a JavaScript Array for collection, and finally use the join method to connect

  var buf = [];    for (var i = 0; i < 100; i++) {      buf.push(i.toString());    }    var all = buf.join("");

Avoid with statements

Similar to a function, the with statement will create its own scope, so it will increase the length of the scope chain of the code to be executed. Due to the search of the additional scope chain, the code to be executed in the with statement is certainly slower than the code to be executed outside. Do not use the with statement when you can not use the with statement.

With (. b. c. d) {property1 = 1; property2 = 2;} // you can replace it with var obj =. b. c. d; obj. property1 = 1; obj. property2 = 2;

Convert a number to a string

It is better to use "" + 1 to convert a number into a string. Although it looks ugly, the efficiency is actually the highest, in terms of performance:

(“” +) > String() > .toString() > new String()

Convert a floating point to an integer.

Many people like to use parseInt (). In fact, parseInt () is used to convert a string to a number, rather than between a floating point and an integer. We should use Math. floor () or Math. round ()

Various types of conversions

var myVar = "3.14159",    str = "" + myVar, // to string     i_int = ~ ~myVar, // to integer     f_float = 1 * myVar, // to float     b_bool = !!myVar, /* to boolean - any string with length                 and any number except 0 are true */    array = [myVar]; // to array

If the toString () method is defined for type conversion, we recommend that you call toString () explicitly, because the internal operation will try the toString () of the object after trying all the possibilities () the method can be converted to a String, so it is more efficient to directly call this method.

Multiple types Declaration

In JavaScript, all variables can be declared using a single var statement. In this way, the statements are combined to reduce the execution time of the entire script, just like the code above, the above code format is also quite standard, which makes it easy to understand.

Insert iterator

For example, var name = values [I]; I ++; the first two statements can be written as var name = values [I ++]

Direct usage

Var aTest = new Array (); // replace it with var aTest = []; var aTest = new Object; // replace it with var aTest = {}; var reg = new RegExp (); // replace it with var reg = /.. // if you want to create a general object with some features, you can also use the literal volume as follows: var oFruit = new O; oFruit. color = "red"; oFruit. name = "apple"; // The preceding code can be rewritten as an object literal: var oFruit = {color: "red", name: "apple "};

Use DocumentFragment to optimize multiple appends

Once you need to update the DOM, consider using document fragments to construct the DOM structure and then add it to the existing documents.

For (var I = 0; I <1000; I ++) {var el = document. createElement ('P'); el. innerHTML = I; document. body. appendChild (el);} // you can replace it with var frag = document. createDocumentFragment (); for (var I = 0; I <1000; I ++) {var el = document. createElement ('P'); el. innerHTML = I; frag. appendChild (el);} document. body. appendChild (frag );

Use an innerHTML value assignment instead of a dom element.

For large DOM changes, using innerHTML is much faster than using standard DOM methods to create the same DOM structure.

Var frag = document. createDocumentFragment (); for (var I = 0; I <1000; I ++) {var el = document. createElement ('P'); el. innerHTML = I; frag. appendChild (el);} document. body. appendChild (frag); // you can replace it with var html = []; for (var I = 0; I <1000; I ++) {html. push ('<p>' + I + '</p>');} document. body. innerHTML = html. join ('');

Replace createElement with template element clone

Many users prefer to use document. write in JavaScript to generate content for pages. In fact, this is less efficient. If you need to insert HTML directly, you can find a container element, such as specifying a div or span, and set their innerHTML to insert their HTML code into the page. Generally, we may use strings to directly write HTML to create nodes. In fact, in this way, 1 cannot guarantee the code validity. 2. The string operation efficiency is low. Therefore, we should use document. createElement () method. If there is a ready-made template node in the document, you should use the cloneNode () method. Because after using the createElement () method, you need to set attributes of multiple elements, using cloneNode () can reduce the number of attribute settings-if you need to create many elements, you should first prepare a template Node

Var frag = document. createDocumentFragment (); for (var I = 0; I <1000; I ++) {var el = document. createElement ('P'); el. innerHTML = I; frag. appendChild (el);} document. body. appendChild (frag); // replace it with var frag = document. createDocumentFragment (); var pEl = document. getElementsByTagName ('P') [0]; for (var I = 0; I <1000; I ++) {var el = pEl. cloneNode (false); el. innerHTML = I; frag. appendChild (el);} document. body. appendChild (frag );

Use firstChild and nextSibling instead of childNodes to traverse dom elements

Var nodes = element. childNodes; for (var I = 0, l = nodes. length; I <l; I ++) {var node = nodes [I]; //… } // Can be replaced with: var node = element. firstChild; while (node ){//...... Node = node. nextSibling;

Delete a dom Node

Before deleting a dom node, you must delete the events registered on the node, whether registered in observe or attachEvent mode. Otherwise, memory cannot be recycled. In addition, the latter should be selected between removeChild and innerHTML = '', because in sIEve (Memory Leak Monitoring Tool), the result of monitoring is that removeChild cannot effectively release dom nodes.

Use event proxy

Any event that can be bubbling can be processed not only on the event target, but also on any ancestor node of the target, with this knowledge, you can attach the event handler to a higher level to handle events with multiple targets. Similarly, when the content is dynamically added and the child nodes need the same event handler function, you can mention event registration to the parent node, so that you do not need to register event listening for each child node. In addition, the existing js library uses the observe method to create event listening, which isolates the circular reference between the dom object and the event processing function. Therefore, we should try to use this method to create event listening.

Repeated call results are saved to local variables in advance.

// Avoid the call overhead var h1 = element1.clientHeight + num1; var h2 = element1.clientHeight + num2; // you can replace it with var eleHeight = element1.clientHeight; var h1 = eleHeight + num1; var h2 = eleHeight + num2;

Note: NodeList

Minimizing the number of NodeList accesses can greatly improve the script performance.

    var images = document.getElementsByTagName('img');    for (var i = 0, len = images.length; i < len; i++) {    }

When writing JavaScript, you must know when to return the NodeList object, which can minimize access to them.

Call getElementsByTagName ()

Obtains the childNodes attribute of the element.
The attributes attribute of the element is obtained.
Access special collections, such as document. forms and document. images.
When using a NodeList object, it can greatly improve the code execution speed.

Optimized cycle

You can use the following methods to optimize the cycle:

Impairment Iteration

Most cycles use an iterator that starts from 0 and increases to a specific value. In many cases, it is more efficient to iterate from the maximum value.

Simplified termination conditions

Since every cycle process calculates the termination condition, you must ensure that it is as fast as possible, that is, to avoid attribute search or other operations, it is best to save the cyclic control value to a local variable, that is to say, the length of an array or list object is saved to a local variable in advance to avoid repeated values in each step of the loop.

Var list = document. getElementsByTagName ('P'); for (var I = 0; I <list. length; I ++ ){//...... } // Replace with: var list = document. getElementsByTagName ('P'); for (var I = 0, l = list. length; I <l; I ++ ){//...... }

Simplified loop body

The loop body is the most executed, so make sure it is optimized to the maximum extent.

Test cycle after use

In JavaScript, we can use three loops: for (;), while (), and for (in). in fact, the efficiency of for (in) in these three loops is very poor, because he needs to query hash keys, as long as they can, they should be used as little as possible. For (;) and while loops, while loops are more efficient than for (;). It may be because of the structure of for (;), and you need to jump back frequently.

Var arr = [1, 2, 3, 4, 5, 6, 7]; var sum = 0; for (var I = 0, l = arr. length; I <l; I ++) {sum + = arr [I] ;}// you can replace it with: var arr = [1, 2, 3, 4, 5, 6, 7]; var sum = 0, l = arr. length; while (l --) {sum + = arr [l];}

The most common for loop and while loop are pre-test loops, while the do-while post-test loop can avoid the calculation of the initial termination condition, so it runs faster.

Expand cycle

When the number of cycles is determined, it is often faster to eliminate loops and use multiple function calls.

Avoid Double Interpretation

If you want to improve code performance, try to avoid strings that need to be interpreted in JavaScript, that is

Use eval functions as few as possible

Using eval is equivalent to calling the interpretation engine again at runtime to run the content, which consumes a lot of time. In addition, the security problems caused by using Eval cannot be ignored.

Do not use the Function Constructor

Do not pass string parameters to setTimeout or setInterval

Var num = 0; setTimeout ('num ++ ', 10); // you can replace it with: var num = 0; function addNum () {num ++ ;} setTimeout (addNum, 10 );

Shorten negative detection

If (oTest! = '# Ff000000') {// do something} if (oTest! = Null) {// do something} if (oTest! = False) {// do something} // although these are all correct, using logical non-operators also has the same effect: if (! OTest) {// do something}

Condition Branch

Sort the condition branches in ascending order of likelihood: This reduces the number of times the interpreter detects the condition.
When multiple (> 2) condition branches under the same condition exist, the efficiency of using switch is higher than that of if: switch Branch selection than that of if, especially in IE. For a 4-branch test, the switch execution time in IE is about half of if.

Use the Three-object operator to replace the condition Branch

If (a> B) {num = a;} else {num = B;} // you can replace it with num = a> B? A: B;

Use Constants

Repeated value: any value used in multiple places should be extracted as a constant.

User Interface string: any string used for display to the user should be extracted to facilitate internationalization
URLs: In Web applications, the resource location is easy to change. Therefore, it is recommended to store all URLs in a public place.
Any value that may be changed: Whenever you use a literal value, you need to ask whether the value will change in the future. If the answer is "yes ", this value should be extracted as a constant.
Avoid comparison with null

Because JavaScript is of a weak type, it does not perform any automatic type check. If you see code that is compared with null, try to replace it with the following technology:

If the value should be a reference type, use the instanceof operator to check its constructor.

If the value should be a basic type, the function typeof checks its type.

If you want an object to contain a specific method name, use the typeof operator to ensure that the method of the specified name exists on the object.

Avoid global traffic

The global variables should all be uppercase letters, and each word is connected by _ underline. Avoid global variables and functions as much as possible, and minimize the use of global variables because all JavaScript contained in a page runs in the same domain. Therefore, if you declare a global variable or global function in your code, the variables and functions of the same name in the script file loaded in the code will overwrite you.

// Bad global variables and global functions var current = null; function init (){//...} function change (){//...} function verify (){//...} // There are many solutions. The recommended method for Christian Heilmann is: // If variables and functions do not need to be referenced outside, you can use a method without a name to package all of them. (Function () {var current = null; function init (){//...} function change (){//...} function verify (){//...}}) (); // If variables and functions need to be referenced outside, you need to put your variables and functions in a "namespace". // here we use a function as the namespace instead of a var, because it is easier to declare a function in the former, and can protect private data myNameSpace = function () {var current = null; function init (){//...} function change (){//...} function verify (){//...} // all functions and attributes that need to be called outside the namespace must be written in return {init: init, // you can even name the function and attribute an alias set: change };};

Respect object ownership

Because JavaScript can modify any object at any time, it can overwrite the default behavior in an unpredictable way, so if you are not responsible for maintaining an object, the object or its method, so you should not modify it, specifically:

Do not add properties for instances or prototypes
Do not add methods for instances or prototypes
Do not redefine existing methods
Do not repeatedly define the methods implemented by other team members, and never modify objects not owned by you. You can create new functions for objects in the following ways:
Create a new object that contains the required functions and use it to interact with related objects.
Create a custom type, inherit the type to be modified, and then add additional functions for the custom type

Loop reference

If the circular reference contains a DOM object or ActiveX object, memory leakage occurs. The consequence of Memory leakage is that, even if the page is refreshed before the browser is closed, the memory will not be released by the browser.

Simple loop reference:

    var el = document.getElementById('MyElement');    var func = function () {      //…    }    el.func = func;    func.element = el;

But this usually does not happen. Loop references usually occur when a closure is added to a dom element as an expendo.

    function init() {      var el = document.getElementById('MyElement');      el.onclick = function () {        //……      }    }    init();

During init execution, the current context is called context. At this time, context references el, el references function, and function references context. At this time, a circular reference is formed.

The following two methods can solve the problem of loop reference:

1) Empty dom object

Function init () {var el = document. getElementById ('myelement'); el. onclick = function (){//...... } Init (); // can be replaced with: function init () {var el = document. getElementById ('myelement'); el. onclick = function (){//...... } El = null;} init ();

Leave el empty. The context does not contain references to dom objects, thus interrupting the circular application.

To return the dom object, use the following method:

Function init () {var el = document. getElementById ('myelement'); el. onclick = function (){//...... } Return el;} init (); // function init () {var el = document. getElementById ('myelement'); el. onclick = function (){//...... } Try {return el;} finally {el = null;} init ();

2) construct a new context

Function init () {var el = document. getElementById ('myelement'); el. onclick = function (){//...... } Init (); // can be replaced with: function elClickHandler (){//...... } Function init () {var el = document. getElementById ('myelement'); el. onclick = elClickHandler;} init ();

Extract the function to the new context. In this way, the context of the function does not include a reference to el, thus interrupting the circular reference.

Dom objects created using javascript must be appended to the page.

In IE, if the dom object created by the script is not appended to the page and the page is refreshed, this part of memory will not be recycled!

Function create () {var gc = document. getElementById ('gc '); for (var I = 0; I <5000; I ++) {var el = document. createElement ('div '); el. innerHTML = "test"; // you can comment out the following sentence to see if the browser is in the task manager. click the button and refresh the gc for memory changes. appendChild (el );}}

Releases the memory occupied by dom elements.

Set innerHTML of the dom element to an empty string to release the memory occupied by its child elements.

In rich applications, users may stay on a page for a long time. You can use this method to release the memory that has accumulated more and more dom elements.

Release javascript objects

In rich applications, memory consumption increases as the number of instantiated objects increases. Therefore, the reference to the object should be released in time so that GC can recycle these memory controls.

Object: obj = null

Object Property: delete obj. myproperty

Array item: Use the splice method of the array to release unused items in the array.

Avoid implicit string packing

Call the string method, such as 'xxx'. length. The browser will perform an implicit packing operation to convert the String into a string object. We recommend that you use the following method to declare strings that may use the String instance method:

var myString = new String(‘Hello World');

Loose coupling

1. Decoupling HTML/JavaScript

Tightly coupled JavaScript and HTML: JavaScript directly written in HTML, using <script> elements containing Inline code, and allocating Event Handlers using HTML attributes

Tightly coupled HTML and JavaScript: JavaScript contains HTML, and innerHTML is used to insert html text to the page.

In fact, we should keep the separation of layers so that we can easily determine the source of errors. Therefore, we should ensure that HTML Rendering should be as isolated from JavaScript as possible.

2. Decoupling CSS/JavaScript

The only source of display problems should be CSS, and the only source of behavior problems should be JavaScript. Maintaining loose coupling between layers makes your applications easier to maintain, so like the following code element. style. color = "red" should be changed to element. className = "edit", and do not embed JavaScript in css using expressions

3. Decoupling applications/event handlers

Separating the application logic from the event handler: An event handler should extract the information from the event object and send the information to a method that processes the application logic. The benefits of doing so first make it easier for you to change the events that trigger a specific process. Second, you can test the code without attaching an event to make it easier to create a unit test.

Performance Considerations

1. Try to use the native Method

2. switch statements are faster than if statements.

Organize case statements in the most likely to impossible order

3. Fast bit operations

Bitwise operations are faster than any Boolean OR arithmetic operations.

4. Clever Use of | and & boolean operators

Function eventHandler (e) {if (! E) e = window. event;} // can be replaced with: function eventHandler (e) {e = e | window. event;} if (myobj) {doSomething (myobj);} // you can replace it with myobj & doSomething (myobj );

Precautions for avoiding errors

1. Add points at the end of each statement

In the if statement, even if the conditional expression has only one statement, use {} to enclose it, so as to avoid logical errors after the statement is added.

2. Exercise caution when using the plus sign

JavaScript is different from other programming languages. In JavaScript, '+' not only indicates the addition of numeric values, but also connects strings. It can also be used as an unary operator to convert strings into numbers. Therefore, improper use may be confused with the auto-incrementing character '+ +', resulting in a computing error.

    var valueA = 20;    var valueB = "10";    alert(valueA + valueB);   //ouput: 2010     alert(valueA + (+valueB)); //output: 30     alert(valueA + +valueB);  //output:30     alert(valueA ++ valueB);   //Compile error

3. Pay attention to the use of the return Statement

A return statement with a return value should not use () to enclose the return value. If the return expression is used, the expression should be in the same line as the return keyword to avoid compression, the compression tool automatically points out the number and returns results inconsistent with those of developers.

 function F1() {      var valueA = 1;      var valueB = 2;      return valueA + valueB;    }    function F2() {      var valueA = 1;      var valueB = 2;      return      valueA + valueB;    }    alert(F1()); //output: 3     alert(F2()); //ouput: undefined

= And =

Avoid assigning values in the condition section of the if and while statements. For example, if (a = B) should be written as if (a = B), but if the comparison is equal, it is best to use the full-level runtime, that is, use = and! The = Operator is equal to the = and! = Will be better. = And! = The operator performs type forced conversion.

var valueA = "1";    var valueB = 1;    if (valueA == valueB) {      alert("Equal");    }    else {      alert("Not equal");    }    //output: "Equal"    if (valueA === valueB) {      alert("Equal");    }    else {      alert("Not equal");    }    //output: "Not equal"

Do not use native syntax

Do not use native syntax to write confusing code. Although the computer can correctly identify and run the code, obscure Code cannot be maintained in the future.

Function return unified type

Although JavaScript is of a weak type, for a function, the previous return of integer data, followed by the return of Boolean values can be compiled and run normally, but in order to be standardized and easy to understand in future maintenance, ensure that the function should return a unified data type

Always check the data type

Check all the data entered by your method for security and availability. Users can enter incorrect data anytime, anywhere. This is not because they are stupid, but because they are very busy and think differently from you. Use the typeof method to check whether the input accepted by your function is valid.

When to use single quotes and double quotes

In JavaScript, double quotation marks and single quotation marks can both represent strings. To avoid confusion, we recommend that you use double quotation marks in HTML and single quotation marks in JavaScript, but to be compatible with various browsers, to avoid errors during parsing, double quotation marks are recommended when defining a JSON object.

Deployment

Run JavaScript validators with JSLint to ensure there are no syntax errors or the Code has no potential questions.
Before deployment, compression tools are recommended to compress JS files.

Unified UTF-8 for file encoding

JavaScript programs should be stored in. js files as much as possible, and should be included in HTML in the form of <script src = "filename. js"> when called. If JavaScript code is not specific to the HTML file, avoid writing JavaScript code directly in the HTML file. This will greatly increase the size of HTML files and will not help code compression and Cache Usage. In addition, the <script src = "filename. js"> label should be placed behind the file, preferably before the </body> label. This reduces the loading time of other components on the page due to loading JavaScript code.
Never ignore code optimization. refactoring is a constant task from the beginning to the end of the project. Only continuous code optimization can improve the code execution efficiency.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.