JavaScript performance Optimization Small knowledge summary _javascript skills

Source: Internet
Author: User
Tags instance method setinterval javascript array

With the development of the network and the speed of the machine, more and more websites use the rich client technology. Now Ajax is one of the most popular ways. JavaScript is an interpreted language, so it can't reach the level of C/java and so on, limiting what it can do on the client, and in order to improve his performance, I want to talk about my experience based on a lot of the tests I've done on JavaScript before. Hopefully it will help you improve your JavaScript scripting performance.

Objective

has been learning JavaScript, but also read the "Sharp development of jquery kernel details and practice," the book's evaluation of only two words sharp, may be the understanding of JavaScript is not completely different or too stupid, More is that they are not good at thinking too lazy to think so that some of the essence is not too deep understanding.

In view of want to let oneself have a promotion, can't enter a broader world, must find a place of their own to live well, so usually intentionally or unintentionally to accumulate some use jquerry common knowledge, especially for the performance requirements of this piece, always think there is a better way to achieve.

Here are some tips I've summed up, just for reference. (I'll start with a headline and then use a short paragraph to explain the meaning and then use a demo to simply say it)

Avoid global lookups

In a function, a global object is stored as a local variable to reduce the global lookup, because accessing a local variable is faster than accessing the global variable

    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 to do this is to save it with a simple variable first.
    function Search () {
      var location = window.location;
      Alert (location.href + location.host);
    }

Timer

If you are running code, you should not use settimeout instead of setinterval, because settimeout Initializes a timer every time, and setinterval only Initializes a timer at the beginning.

var timeouttimes = 0;
    function timeout () {
      timeouttimes++;
      if (Timeouttimes <) {
        settimeout (timeout);
      }
    }
    Timeout ();
    Can be replaced by:
    var intervaltimes = 0;
    function interval () {
      intervaltimes++;
      if (Intervaltimes >=) {
        clearinterval (interv);
      }
    }
    var interv = setinterval (interval, 10);

string concatenation

If you want to connect multiple strings, you should use + = less, such as

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

should be written as S+=a + B + C;

If you are collecting strings, such as + + for the same string multiple times, it is best to use a cache, use a JavaScript array to collect, and finally connect by using the Join method

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

Avoid with statement

Like a function, the WITH statement creates its own scope, this increases the length of the scope chain in which the code is executed, and because of the additional scope chain lookup, the code executed in the WITH statement will be slower than the code executed outside, and should not use the WITH statement as much as possible without using the WITH statement.

 With (a.b.c.d) {
      property1 = 1;
      Property2 = 2;
    }
    Can be replaced by:
    var obj = a.b.c.d;
    Obj.property1 = 1;
    Obj.property2 = 2;

Converts numbers to strings

The best use of "" + to convert the number to a string, although it looks more ugly, but in fact this efficiency is the highest, performance up to say:

("+" > String () >. toString () > New String ()

Floating-point number converted to integral type

A lot of people like to use parseint (), in fact parseint () is used to convert strings into numbers rather than floating-point and integer conversions, 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 you define the ToString () method for type conversion, it is recommended that you explicitly call ToString (), because an internal operation tries to convert the object's ToString () method to a string after attempting all possibilities, so it is more efficient to call this method directly

Multiple type declarations

In JavaScript, all variables can be declared using a single VAR statement, which is a combination of statements to reduce the execution time of the entire script, just like the code above, the code format is pretty standard, so that people see it.

Insert Iterator

such as Var name=values[i]; i++ the previous two statements can be written as Var name=values[i++]

Use Direct quantity

var atest = new Array (); Replace with
    var atest = [];
    var atest = new Object; Replace with
    var atest = {};
    var reg = new RegExp (); Replace with
    var reg =/.. /;
    If you want to create a generic object with some attributes, you can also use literal quantities, as follows:
    var ofruit = new O;
    Ofruit.color = "Red";
    Ofruit.name = "Apple";
    The preceding code can be rewritten with object literals:
    var ofruit = {color: "Red", Name: "Apple"};

Use DocumentFragment to optimize multiple append

Once you need to update the DOM, consider using document fragmentation to build the DOM structure and then add it to an existing document.

for (var i = 0; i < 1000 i++) {
      var el = document.createelement (' P ');
      el.innerhtml = i;
      Document.body.appendChild (EL);
    Can be replaced by:
    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 a innerhtml assignment instead of building a DOM element

For large DOM changes, using innerHTML is much faster than creating the same DOM structure using a standard DOM method.

    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);
    Can be replaced by:
    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 people like to use document.write in JavaScript to generate content for a page. 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 own HTML code into the page. Normally we might use a string to write HTML directly to create a node, in fact, 1 can't guarantee the validity of the code 2 string operation is inefficient, so it should be using the Document.createelement () method, and if there are ready-made boilerplate nodes in the document, You should use the CloneNode () method, because after using the createelement () method, you need to set the properties of multiple elements, using CloneNode () You can reduce the number of properties set-also if you need to create a lot of 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);
    To be replaced by:
    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 by:
    var node = element.firstchild;
    while (node) {
      //
      ..... node = node.nextsibling;

Delete a DOM node

Before deleting a DOM node, be sure to remove the event that is registered on that node, either in observe or attachevent, or it will result in memory that cannot be reclaimed. In addition, between RemoveChild and Innerhtml= ', try to choose the latter. Because the result of monitoring in the sieve (Memory leak monitoring tool) is that the DOM node is not effectively freed with RemoveChild

Using Event proxies

Any bubbling event can be handled not only on the event target, can also be handled on any ancestor node of the target, using this knowledge to attach event handlers to higher places to handle event handling for multiple targets, and similarly, for content to increase dynamically and child nodes need the same event handler function, Event registration can be mentioned on the parent node, so there is no need to register event monitoring for each child node. In addition, the existing JS library uses the observe way to create event monitoring, its implementation of the isolation of DOM objects and event processing functions of the circular reference, so should try to use this way to create event monitoring

Reuse of call results, saving in advance to local variables

   Avoid calling cost of multiple values
    var h1 = element1.clientheight + num1;
    var h2 = element1.clientheight + num2;
    Can be replaced by:
    var eleheight = element1.clientheight;
    var H1 = eleheight + num1;
    var h2 = eleheight + num2;

Pay attention to NodeList

Minimizing the number of access nodelist can greatly improve the performance of scripts

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

When writing JavaScript, be sure to know when to return NodeList objects so that you can minimize access to them

A call to getElementsByTagName () was made

Gets the ChildNodes property of an element
Gets the attributes property of an element
Access to special collections such as document.forms, document.images, etc.
To understand that when using a NodeList object, reasonable use can greatly increase code execution speed

Optimizing loops

You can use the following ways to optimize loops

Reduced-value iterations

Most loops use an iterator that starts at 0 and increases to a particular value, and in many cases, the iterator that is decreasing the value in the loop is more efficient when it starts at the maximum value.

Simplifying termination conditions

Because each loop process computes the termination condition, it must be guaranteed as fast as possible, that is, to avoid property lookups or other operations, preferably by saving the amount of the loop control to a local variable, that is, to save the length to a local variable in advance when the array or list object is traversed, Avoid repeating values at each step in the loop.

  var list = document.getElementsByTagName (' P ');
    for (var i = 0; i < list.length i++) {
      //...
    }
    To be replaced by:
    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

Test loops after use

In JavaScript, we can use a for (;;), a while (), for (in) three loops, in fact, in these three loops for (in) efficiency is extremely poor, because he needs to query the hash key, as long as you can, should be as little as possible. for (;;) And while loops, while loops are more efficient than for (;;), probably because of a for (;;) The structure of the problem requires frequent jumps back.

    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];
    }
    can be considered for replacement:
    var arr = [1, 2, 3, 4, 5, 6, 7];
    var sum = 0, L = arr.length;
    while (l--) {
      sum + = Arr[l];
    }

The most commonly used for and while loops are the pre-test loops, and, such as Do-while, this post test loop avoids the calculation of the initial termination condition and therefore runs faster.

Expand loop

When the number of cycles is determined, eliminating loops and using multiple function calls is often quicker.

Avoid double explanations

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

Use the Eval function as little as possible

Using Eval is equivalent to invoking the interpretation engine at run time to run the content, consuming a lot of time, and security issues with Eval are not to be overlooked.

Do not use the function constructor

Do not pass string arguments to SetTimeout or setinterval

var num = 0;
    settimeout (' num++ ', ten);
    Can be replaced by:
    var num = 0;
    function Addnum () {
      num++;
    }
    SetTimeout (Addnum, 10);

Reduce negative detection

    if (otest!= ' #ff0000 ') {
      //do something
    }
    if (otest!= null) {
      //do something
    }
    if (Otest!= fals e) {
      //do something
    }
    //Although these are all correct, the same effect can be done with a logical non-operator:
    if (!otest) {
      //do something
    }

Conditional Branch

Arrange conditional branches, in probability order from high to Low: you can reduce the number of times the interpreter has probed the condition
When multiple (>2) conditional branches of the same condition are branching, the efficiency of using switch over If:switch branch selection is higher than if, especially in IE. 4 branch of the test, ie under the switch execution time is about half of if.

Substituting a conditional branch with the three-mesh operator

if (a > B) {
      num = A;
    } else {
      num = b;
    }
    Can be replaced by:
    num = a > B a:b;

Using constants

Duplicate value: Any value that is used in multiple places should be extracted as a constant

User interface string: Any string that is displayed to the user should be extracted to facilitate internationalization
URLs: In Web applications, resource locations are easily changed, so it is recommended to store all URLs in a common place
Any value that may change: every time you use a literal value, you ask yourself whether the value will change in the future, and if the answer is "yes", then the value should be extracted as a constant.
Avoid comparing to NULL

Because JavaScript is weakly typed, it does not do any automatic type checking, so if you see code that compares to NULL, try using the following techniques to replace

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

If the value should be a base type, the action typeof check its type

If you want the object to contain a specific method name, use the typeof operator to ensure that the method that specifies the name exists on the object

Avoid global volume

The global variable should be all uppercase and each word is connected by an underscore. Avoid global variables and functions as much as possible, minimizing the use of global variables because all JavaScript contained in one page runs in the same domain. So if you have a global variable or global function declared in your code, the same variable and function in the script file that is loaded in the following code will overwrite (overwrite) your.

Bad global variables and global functions
var current = null;
function init () {
//...
}
function Change () {
  //...
}
function Verify () {
  //...
}
There are a lot of solutions, Christian Heilmann suggests:
//If variables and functions do not need to be "outside" references, then you can wrap them all up with a method that does not have a name.
(function () {
var current = null;
function init () {
  //...
}
function Change () {
  //...
}
function Verify () {
  //...
}
}) ();
If variables and functions need to be referenced "outside", you need to place your variables and functions in a "namespace"
//We use a function as a namespace instead of a var because it is simpler to declare a function in the former and to protect the privacy data
MyNamespace = function () {
  var current = null;
  function init () {
    //...
  }
  function Change () {
    //...
  }
  function Verify () {
    //...
  }
All functions and properties that need to be called outside the namespace are written in return.
  {
    init:init,
    //Even you can name an alias Set:change} for functions and
    attributes
  ;

Respect for the ownership of objects

Because JavaScript can modify any object at any time, it can override the default behavior in an unpredictable way, so if you're not responsible for maintaining an object, its object, or its method, then you should not modify it, specifically, by saying:

Do not add attributes for instance or prototype
Do not add methods for instance or prototype
Do not redefine a method that already exists
Do not repeatedly define methods that other team members have implemented, never modify objects that are not owned by you, and you can create new functionality for objects in the following ways:
Create a new object that contains the functionality you want and use it to interact with related objects
Create a custom type, inherit the type that needs to be modified, and then add additional functionality to the custom type

Circular Reference

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

Simple Circular Reference:

    var el = document.getElementById (' myelement ');
    var func = function () {
      //...
    }
    El.func = func;
    Func.element = El;

But this is not usually the case. Usually a circular reference occurs when a closure is added to a DOM element as a expendo.

    function init () {
      var el = document.getElementById (' myelement ');
      El.onclick = function () {
        //...
      }
    }
    Init ();

At the time Init is executing, the current context we are called contexts. At this time, the context references the El,el reference to the Function,function reference context. A circular reference is formed at this time.

The following 2 ways to resolve circular references:

1 Empty DOM Object

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

The El is empty, and the context does not contain a reference to the DOM object, which interrupts the circular application.

If we need to return the DOM object, we can use the following method:

   function init () {
      var el = document.getElementById (' myelement ');
      El.onclick = function () {
        //...
      }
      Return el;
    }
    Init ();
    Can be replaced by:
    function init () {
      var el = document.getElementById (' myelement ');
      El.onclick = function () {
        //...
      }
      try {return
        el;
      } finally {
        el = null;
      }
    }
    Init ();

2) Constructing a new context

  function init () {
      var el = document.getElementById (' myelement ');
      El.onclick = function () {
        //...
      }
    }
    Init ();
    Can be replaced by:
    function Elclickhandler () {
      //...
    }
    function init () {
      var el = document.getElementById (' myelement ');
      El.onclick = Elclickhandler;
    }
    Init ();

The function is drawn into the new context so that the context of the function does not contain a reference to El, thus interrupting the circular reference.

Dom objects created through JavaScript must be append to the page

IE, the DOM object created by the script, if not append to the page, refresh the page, 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";
        The following sentence can be commented out, look at the browser in Task Manager, click on the button and then refresh the memory changes
        gc.appendchild (EL);
      }
    

Freeing memory occupied by DOM elements

Sets the DOM element's innerHTML to an empty string, freeing the memory occupied by its child elements.

In rich applications, users may stay on a page for a long time and use this method to release the memory used by more and more DOM elements that accumulate.

Releasing a JavaScript object

In rich applications, memory consumption becomes larger as the number of instantiated objects increases. So a reference to the object should be released in time for the GC to reclaim the memory controls.

object: obj = null

Object properties: Delete Obj.myproperty

Array item: Using the Splice method of an array to free the unused item in an array

Avoiding implicit boxing of strings

For method calls to string, such as ' xxx '. Length, the browser makes an implicit boxing operation, converting the string to one string object first. The recommended way to declare a string with the possibility of using a string instance method is to use the following notation:

var myString = new String (' Hello world ');

Loosely coupled

1, decoupling Html/javascript

Tightly coupled JavaScript and HTML: JavaScript written directly in HTML, using <script> elements that contain inline code, assigning event handlers using HTML attributes, and so on

Tight coupling of HTML and javascript: JavaScript contains HTML and then uses innerHTML to insert a section of HTML text into the page

It should be a separation of the layers so that it's easy to identify the source of the error, so we should make sure that HTML rendering should be kept separate from JavaScript as much as possible

2, decoupling Css/javascript

The only source of the problem should be CSS, and the only source of behavioral problems should be JavaScript, where loose coupling between layers can make your application easier to maintain, so code like the following element.style.color= "Red" Try to change to element.classname= "edit", and do not embed JavaScript in the CSS through an expression

3. Decoupling application/Event handlers

Separating the application logic from the event handler: an event handler should be extracted from the event object and transmitted to a method that handles the application logic. The benefits of doing this first make it easier to change the events that trigger a particular procedure, and then you can test the code without attaching an event to make it easier to create unit tests

Performance considerations

1. Use the native method as far as possible

2, switch statement relative to if faster

Organize case statements in the most likely to most unlikely order

3, bit operation faster

The bitwise operation is faster than any Boolean operation or arithmetic when doing a numeric operation.

4, skillfully use | | and && Boolean operators

 function EventHandler (e) {
      if (!e) e = window.event;
    }
    Can be replaced by:
    function EventHandler (e) {
      e = e | | window.event;
    }
    if (myobj) {
      dosomething (myobj);
    }
    Can be replaced by:
    myobj && dosomething (myobj);

Avoid mistakes should be noted in the place

1, each statement must be appended with a semicolon

In an if statement, even if a conditional expression has only one statement to enclose it in {}, to prevent subsequent logical errors if a statement is added

2, use the + number should be cautious

JavaScript differs from other programming languages in that, in JavaScript, ' + ' can be used as a unary operator in addition to adding numeric values and strings, and converting strings to numbers. Therefore, if improperly used, it may be confused with the self-added ' + + ' and cause a calculation error

    var Valuea =;
    var valueb = "Ten";
    Alert (Valuea + valueb);   ouput:2010 
    Alert (Valuea + (+VALUEB));//output:30 
    alert (Valuea + +valueb)  ; output:30 
    Alert (Valuea + + valueb);   Compile Error

3. Use return statement to pay attention to

Return statement with return value do not enclose the returned value with () parentheses, and if the expression is returned, the expression should be on the same line as the return keyword to avoid compression, and the compression tool automatically adds a semicolon that results in inconsistent returns with the developer

 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

The difference between = = and = =

Avoid assigning values in the conditional part of the IF and while statements, such as if (a = b), and should be written as if (a = = B), but if comparisons are equal, it is best to use the congruent operator, which means that the = = and!== operators will be better than = = and!=. the = = and!= operators do type casts

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 biased syntax

Do not use biased grammar, write confusing code, although the computer can correctly identify and run, but obscure code is inconvenient to maintain

function returns the uniform type

Although JavaScript is weakly typed, for functions, the previous return of integer data, the return of Boolean values in the compilation and operation of the normal pass, but in order to standardize and later maintenance is easy to understand, you should ensure that the function should return a unified data type

Always check data type

To check all data entered by your method, on the one hand, for security, but also for usability. Users can enter the wrong data anytime, anywhere. This is not because they are stupid, but because they are busy and think differently. Use the TypeOf method to detect whether your function accepts input that is legitimate

When to use single quotes and when to use double quotes

While in JavaScript, double quotes and single quotes can represent strings, in order to avoid clutter, we recommend using double quotes in HTML to use single quotes in JavaScript, but in order to be compatible with individual browsers and to parse without errors, when defining a JSON object, It's best to use double quotes

Deployment

Run JavaScript validators with JSLint to make sure that there are no syntax errors or that the code has no potential to ask
It is recommended that you compress the JS files using the compression tool before deployment

File encoding Unified with UTF-8

JavaScript programs should be included as much as possible in the. js file, in the form of <script src= "Filename.js" > in HTML when called. If the JavaScript code is not specific to the HTML file, you should try to avoid writing JavaScript code directly in the HTML file. Because this will greatly increase the size of the HTML file, is not conducive to the compression of the code and the use of caching. In addition, the <script src= "filename.js" > label should be placed at the back of the file, preferably in front of the </body> tag. This reduces the load time that affects other components in the page by loading JavaScript code.
Never ignore code optimization work, refactoring is a project from the beginning to the end of the need for continuous work, only the continuous optimization of code to make the execution of code more efficient

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.