High-performance JavaScript notes: optimizing the performance of Dom operations in browsers (I)

Source: Internet
Author: User

Frequent Dom operations are very performance-consuming. However, in rich web applications, we have to write scripts to deal with Dom. How can we optimize this performance bottleneck, consider the following three situations:

  1. Access and modify DOM elements
  2. Modifying the DOM style will cause page re-painting and re-layout.
  3. Respond to users through DOM Event Handler

  Access and modify DOM elements

In browsers, Dom implementation and JavaScript implementation are usually independent of each other. The following describes the rendering engine and JS engine of mainstream browsers:

Browser Rendering Engine (kernel) JS Engine
IE Mshtml. dll (Trident) JScript
Chrome WebCore (WebKit) V8
Firefox Gecko Spider-monkey/tracemonkey
Safari WebCore (WebKit) Javascriptcore/squirrelfish

Why does Dom access affect performance? This is because the two independent parts are connected through their respective interfaces, resulting in performance loss. In a metaphor, we regard dom as an island and JavaScript as another island. The two are connected by a toll-free bridge. Every time javascript accesses Dom, we need to bridge the bridge, pay a bridge fee. The cost is naturally high when the back-to-back traffic is too high. So we have to find ways to reduce the number of bridge times.
The cost of accessing the DOM element is to pay a "bridge fee". Modifying the DOM element will cause the browser to recalculate the geometric changes of the page. If the DOM element is modified cyclically, the cost can be imagined. The following code:

Function innerhtmlloop1 () {for (var count = 0; count <10000; count ++) {document. getelementbyid ("test"). innerhtml + = "add content ";}}

In this Code, each cycle accesses the DOM element twice: one is to read the content of the innerhtml attribute, and the other is to write the new content into it. Therefore, an optimization method is to use a local variable to store the updated content and write the updated content at the end of the Loop:

Function innerhtmlloop2 (){
VaR content = ""; for (var count = 0; count <10000; count ++) {content + = "add content";} document. getelementbyid ("test "). innerhtml + = content ;}

Obviously, the "bridge fee" paid by innerhtmlloop2 is less, because it only accesses DOM elements twice, reads at a time, and writes at a time. So the general rule is: Do your best to be in your own scope (JavaScript Island), and do not often get out of the box. (It is said that in Guangzhou, do not make friends if the monthly salary is less than 5 K, you know !).

Comparison of the two methods for updating pages: innerhtml and Dom (for example, document. createlment ). The answer to high-performance JavaScript programming is: the performance is not much different. innerhtml is better and easy to use. Another way to update the page is to clone the node -- element. clonenode ().

  Operations on HTML Sets

  The HTML set is an array object of classes used to store Dom node references. You can obtain such a set using the following methods or attributes:

  1. Document. getelementsbyname ()
  2. Document. getelementsbytagname ()
  3. Document. getelementsbyclassname ()
  4. Document. Images returns references to all image objects in the document.
  5. Document. Links returns references to all area and link objects in the document.
  6. Document. Forms returns reference to all form objects in the document.
  7. Document. Forms [0]. Elements returns all elements of the first form in the document.

  The HTML set queries the document information in real time. That is to say, when you use this set, it automatically queries the latest information of the document.. See the following code:

1 var allDivs = document.getElementsByTagName("div");2 for(var i=0;i<allDivs.length;i++){3     document.body.appendChild(document.createElement("div"));4 }

For example, the code above is actually an endless loop, because every time you access the Length attribute of the DIV set, it recalculates the number of DIV elements in the document. This is the source of inefficient HTML sets. To improve the Code, use a local variable to save the Length attribute of the DIV set: For (VAR I = 0,Len = alldivs. Length; I <Len; I ++ ){...}

The length used to access the HTML set is slower than the length of the array. Therefore, to access the length of the number of such collection classes, we should first save it with a local variable: var Len = set. length;

In addition,Accessing an array is faster than accessing an HTML set.Therefore, we can convert the HTML set into an array before performing the corresponding operation:

// Convert the HTML set to an Array Function toarray (Coll) {for (var a = [], I = 0, Len = Coll. legnth; I <Len; I ++) {A [I] = Coll [I];} return a;} // use VaR coll = document. getelementsbytagname ("Div"); var divs = toarray (Coll );

Someone may ask, is it worthwhile to use an array copy? It depends on the situation. However, another option is to use local variables:

Function loopcolletion () {var coll = document. getelmentsbytagname ("Div"), Len = Coll. length, El = NULL; For (VAR I = 0; I <Len; I ++) {El = Coll [I]; // then access the local variable El }}

Many browsers provide API functions to return element nodes. These APIs are native, so use them whenever possible. Lists some Dom attributes:

  

All properties listed can be supported by ff, Safari, chrome, opera, and ie6-8 only support children.

Traversing children is faster than childnodes because there are fewer set items. Spaces in the HTML source code are actually text nodes, but they are not included in children.

There are also two better selector APIs:Document. queryselectorall() AndDocument. queryselector(). The former receives a CSS selector string parameter and returns a nodelist array object instead of an HTML set. The latter returns only the first node that meets the query conditions. Unfortunately, IE6 and 7 do not support these two APIs.

PS: It's not easy to write a blog post. It took several hours, but it's a good habit to consolidate your knowledge. This blog is my study notes ~

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.