High-performance JavaScript (record three)

Source: Internet
Author: User
Tags tagname

The DOM (Document Object model) is a separate language that is used to manipulate the program interfaces (APIs) of XML and HTML documents. In the browser, it is used primarily to work with HTML documents, as well as to get XML documents in a Web program and to access the data in the document using the DOM API. Although the DOM is a language-agnostic API, its interface in the browser is implemented in JavaScript. Client-side scripting is mostly about dealing with the underlying documents.

The access and modification of the DOM comes at a cost. For example: Dom and JS are each an island, there is only a toll bridge connection. Every time JS accesses the DOM, it is equivalent to the bridge, and pay a bridge fee. The number of visits is more, the cost is higher. This is the DOM access, and the cost of the modification is even higher, because modifying the DOM causes the viewer to recalculate the page's geometric changes. The worst case scenario is accessing or modifying elements in a loop, especially iterating over the collection of HTML elements.

//more slowlyfunctionInnerhtmlloop () { for(varCount = 0;count < 15000;count++) {Document.getelmentbyid ("id"). InnerHTML + =str; The problem with}//is that the element is accessed two times per iteration of the loop: Read the innerHTML property value one time, and rewrite it another time. //more quicklyfunctionInnerHTMLLoop2 () {varContent = ' ';  for(varCount = 0;count < 15000;count++) {countent+=str; } document.getElementById ("id"). InnerHTML + =content;}

General rule: Reduce the number of accesses to the DOM and leave the operation as far as possible at the ECMAScript end of the process.

Question: Is it good to modify the page area with the native Dom method of the innerHTML property or Document.createelement ()?

Answer: Almost everything, except for the latest version of the WebKit kernel, the innerHTML will be faster. If you are updating a large piece of HTML in an operation that is demanding performance, it is recommended to use innerHTML because it runs faster in most of the viewers. However, most of the daily operations are not very different, so it should be based on readability, stability, team habits, code style to decide which method to use.

Node cloning: Another way to update page content using the DOM method is to clone an existing element instead of creating a new element-in other words, using element.clonenode () instead of document.createelement (). In most viewers, node cloning is more efficient, but not obvious.

HTML collection: An HTML collection is a class array object that contains a DOM node reference.

The return value of the following method is the collection: Document.getelementsbyname (), Document.getelementsbyclassname (), document.getElementsByTagName ();

The following properties also return the HTML collection: Document.images, Document.links, document.forms, document.forms[0].elements;

The above method and property return values are HTML collection objects, which are lists of class arrays (not real arrays, because there are no methods such as push () and slice ()), but provide an array-like length property, and can also access the elements in the list in the form of a numeric index. The DOM standard defines: The HTML set exists in real time in a "suspended animation" state, meaning that it is updated automatically when the underlying document object is updated. In fact, the HTML collection remains connected to the document, and every time you need the latest message, the process of executing the query repeats, even if you just get the number of elements in the collection, resulting in performance degradation.

// An unexpected cycle of death var alldivs = document.getElementsByTagName ("div");  for (var i = 0;i < alldivs.length;i++) {    document.body.appendChild (document.createelement ("DIV" ))}

This is because a dead loop caused by the automatic updating of the HTML assembly alldivs.length the current state of the underlying document and increases with the iteration.

//Reading the length of a collection is much slower than reading the length of an ordinary array, because it is queried every time. functionToArray (coll) { for(vari = 0,a = [],len = coll.length; i<len;i++) {A[i]=Coll[i]; }    returnA;}varcoll = document.getelementsbytagname ("div");vararr =ToArray (coll);//compare the following two functions://more slowlyfunctionloopcollection () { for(varCount = 0;count < coll.length;count++){        //Code Handling   }}//reading the length property of an element collection causes the collection to be updated, which improves performance consumption. Optimization: Caches the set length into a local variable, and then uses the variable in the loop's conditional exit statement. Performance is the same as Loopcoiedarray (). //more quicklyfunctionLoopcopiedarray () { for(varCount = 0;count < arr.length;count++){        //Code Handling}}

In many cases, if you only need to traverse a relatively small collection, the cache length is sufficient. Because although traversing an array is faster than traversing the collection, it also brings additional consumption, so it is worthwhile to consider the use of array copies.

Use local variables when accessing collection elements: the slowest version reads the global document every time, the optimized version caches a reference to the collection, and the fastest version stores the current collection element in a variable.

//more slowlyfunctionCollectionglobal () {varcoll = document.getelementsbytagname ("div"), Len=coll.length, name= ' ';  for(varCount = 0;count < len;count++) {Name= document.getElementsByTagName ("div") [Count].nodename; Name= document.getElementsByTagName ("div") [Count].nodetype; Name= document.getElementsByTagName ("div") [Count].tagname; }     returnname;}//more quicklyfunctioncollectionlocal () {varcoll = document.getelementsbytagname ("div"); Len=coll.length, name= ' ';  for(varCount = 0;count < len;count++) {Name=Coll[count].nodename; Name=Coll[count].nodetype; Name=Coll[count].tagname; }     returnname;}//the fastestfunctioncollectionnodeslocal () {varcoll = document.getelementsbytagname ("div"); Len=coll.length, name= ", el=NULL;  for(varCount = 0;count < len;count++) {El=Coll[count] Name=El.nodename; Name=El.nodetype; Name=El.tagname; }     returnname;}

Traversing the DOM

  Get DOM element: ChildNodes gets the collection of elements, nextsibling to get each adjacent element.

To traverse an element's child nodes in a non-recursive way:

functiontestnextsibling () {varel = document.getElementById ("mydiv"), ch= El.firstchild,name = ";  Do{Name=Ch.nodename; } while(ch =ch.nextsibbling); returnname;};functiontestchildnodes () {varel = document.getElementById ("mydiv"); CH=el.childnodes, Len.= Ch.length,name = ";  for(varCount = 0;count < len;count++) {Name=Ch[count].nodename; }    returnname;};

NextSibling and Childnode two methods run for almost equal time, only in IE, nextsibling performance is higher.

ELEMENT nodes: In some cases, you only need to access the element nodes, so it is likely that you will want to check the type of the returned node and filter out non-element nodes in the loop. These types of checks and filtering are actually unnecessary DOM operations. Most browser-provided APIs only return element nodes.

Replacing childnodes with children is faster because there are fewer collection items.

Selector Api:queryselectorall () (using CSS selectors to position nodes) The native Dom method is much faster than using JS and Dom to traverse the lookup element.

Redraw and rearrange:

The browser finishes downloading all the components on the page: HTML tags, js, css, and images will parse and generate two internal data structures: the DOM tree (which represents the page structure) and the rendering tree (indicating how the DOM nodes are displayed). Once completed, the viewer starts drawing the page elements. When DOM changes affect the geometry of the element, the viewer needs to recalculate the geometry of the element, as well as the geometry properties and position of the other elements. The reflow and redraw occurs.

Reflow: The viewer invalidates the affected portions of the render tree and reconstructs the render tree.

Occurrence time: Add or remove visible DOM elements, change element position, change element size, change content, page renderer initialization, browser window size change.

Redraw: The viewer redraws the affected section to the screen after the reflow is complete.

Minimize reflow and redraw: To reduce the number of occurrences, you should merge the DOM and style changes multiple times and then process them one at a time.

Bulk Modify DOM: When you need to do a series of actions on DOM elements, you can reduce the number of reflow and redraw times by leaving elements out of the document flow, applying multiple changes to them, and bringing elements back to the document.

//Update common functions for specifying node datafunctionappenddatatoelement (appendtoelement,data) {varA,li;  for(vari = 0;max = Data.length;i < max;i++) {a= Document.createelement ("a"); A.href=Data.data[i].url;        A.appendchild (document.createTextNode (data[i].name)); Li= document.createelement ("li");        Li.appendchild (a);    Appendtoelement.appendchild (LI); }};//do not consider rearrangement issuesvarUL = document.getElementById ("Myul"); appenddatatoelement (ul,data);//optimization, leaving the DOM out of the document, reducing reflow//method One hides the element, applies the modification, and re-displaysvarUL = document.getElementById ("Myul"); Ul.style.display= "None"; appenddatatoelement (ul,data); Ul.style.display= "Block";//method Two uses the document fragment (Doc fragment) to build a subtree outside the current DOM and then copies it back to the documentvarFragment =document.createdocumentfragment (); Appenddatatoelement (Fragment,data);d Ocument.getelementbyid ("Myul"). appendchild (fragment);//Method Three copies the original element to a node that is out of the document, modifies the copy, and then replaces the original elementvarOld = document.getElementById ("Myul");varClone = Old.clonenode (true); appenddatatoelement (Clone,data); +old.parentnode.replacechhild (Clone,old);

Note: It is recommended to use document fragments because they produce the fewest number of DOM traversal and rearrangement.

There are two more ways to optimize reflow and redraw: When you are getting layout information, when you cache layout information and Process page animations, leave the element out of the animation stream (Note: If you use CSS extensively: hover this pseudo-selector will significantly slow down the response).

  Event delegate:

  When a large number of elements exist on a page, and each one or more times the event handler is bound, each binding event handler has a cost, either aggravating the page load (more code), or increasing the execution time of the run period. A simple and elegant technique for handling DOM events is the event delegate. Based on: The event is bubbling over layers and can be captured by the parent element.

//For exampledocument.getElementById ("menu"). onclick =function(e) {//Viewer TargetE = e | |window.event; vartarget = E.target | |e.srcelement; varPageid,hrefparts; //only care about hrefs, non-link clicks will exit    if(Target.nodename!== "A" ){        return; }    //find the page ID from the linkHrefparts = Target.href.split ("/"); PageID= hrefparts[Hrefparts.length-1 ]; PageID= Pageid.replace (". html", "" "); //Update pageAjaxrequest ("Xhr.php?page" +id,updatepagecontents); //Viewer organizes default behavior and cancels bubbling    if(typeofE.preventdefault = = = "function") {e.preventdefault ();    E.stoppropagetion (); }Else{E.returnvalue=false; E.cancelbubble=true; }};

High-performance JavaScript (record three)

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.