Accelerate javascript: optimize Dom operations

Source: Internet
Author: User

Original article: speeding up javascript: working with the DOM

Author: keekim Heng, Google Web Developer

Http://www.blogjava.net/emu/archive/2010/03/01/314185.html

When we develop Internet rich applications (RIA), we often write some JavaScript scripts to modify or add page elements. These tasks are completed by Dom-or Document Object Model, our implementation will affect the application response speed.

Dom operations can cause reflow in the browser. This is a computation process in the browser that determines how page elements are displayed. Modifying the DOM directly, modifying the CSS style of the element, and modifying the window size of the browser will trigger re-resolution. Reading the layout attributes of an element, such as offsetheithe or offsetwidth, triggers re-resolution. Re-resolution takes computing time. Therefore, the less trigger of re-resolution, the faster the application will be.

Dom operations usually involve modifying the elements on an existing page or creating a new page element. The following four optimization schemes cover modifying and creating DOM nodes, helping you reduce the number of times that the browser is re-resolved.

Solution 1: Modify the DOM by switching the CSS Class Name

This solution allows us to modify multiple style attributes of one element and its child elements at a time and trigger re-resolution only once.

Requirements:

(EMU Note: when the original author writes this article, his mind is obviously short-circuited, and the problems to be solved in the out-of-the-flow Dom manipulation mode are put here, but from demonstrationCodeIt is easy to understand the problems that the author really wants to describe, so EMU will not translate the original text)

Now we need to write a function to modify several style rules of a hyperlink. It is easy to implement. Just change the attributes corresponding to these rules one by one. However, each modification to a style attribute causes a page re-resolution.

 
Function selectanchor (element) {element. style. fontweight = 'bold '; element. style. textdecoration = 'none'; element. style. Color =' #000 ';}

Solution

To solve this problem, we can first create a style name and place all the style rules to be modified on this class name. Then we add this new class name to the hyperlink, you can add several style rules and trigger re-resolution only once. This mode also achieves separation of performance and logic.

 
. Selectedanchor {font-weight: bold; text-Decoration: none; color: #000;} function selectanchor (element) {element. classname = 'selectedanchor ';}

Solution 2: Modify the DOM in the non-rendering Area

(EMU note: the author once again short-circuited his mind here, and introduced the documentfragment Dom generation mode here, So EMU has to make another use of it)

The previous solution solves the problem of modifying a hyperlink. When you need to make the same changes to many hyperlinks at a time, this solution can be used.

Requirement

This is the requirement. We need to write a function to modify the style name (classname) attribute of all hyperlinks in a child element of a specified element. To achieve this, we can traverse each Hyperlink and modify their style names to complete the task. However, each modification to a hyperlink causes a re-resolution.

 
Function updateallanchors (element, anchorclass) {var anchors = element. getelementsbytagname ('A'); For (VAR I = 0, length = anchors. length; I <length; I ++) {anchors [I]. classname = anchorclass ;}}

Solution

To solve this problem, we can remove the modified specified element from the Dom, modify all the hyperlinks, and insert the element back to its original position. To complete this complex operation, we can first write a reusable function, which not only removes the DOM node, but also returns a function that inserts the element back to its original position.

/*** Remove an element and provide a function that inserts it into its original position * @ Param element {element} the element to be temporarily removed * @ return {function} a function that inserts the element into its original position **/function removetoinsertlater (element) {var parentnode = element. parentnode; var nextsibling = element. nextsibling; parentnode. removechild (element); return function () {If (nextsibling) {parentnode. insertbefore (element, nextsibling);} else {parentnode. appendchild (element );}};}

With the above function, we can modify those hyperlinks on an element that does not need to be parsed and rendered. In this way, only one re-resolution is triggered when elements are removed and inserted.

Function updateallanchors (element, anchorclass) {var insertfunction = removetoinsertlater (element); var anchors = element. getelementsbytagname ('A'); For (VAR I = 0, length = anchors. length; I <length; I ++) {anchors [I]. classname = anchorclass;} insertfunction ();}

Solution 3: one-time Dom Element Generation

This solution allows us to create an element only trigger re-resolution once. After the element is created, perform all the necessary modifications before inserting it into the Dom.

Requirement

The requirement is that a function is implemented to insert a hyperlink element to a specified parent element. You can set the display text and style classes for this hyperlink at the same time. We can do this: Create an element, insert it to the Dom, and set the corresponding attributes. This triggers three re-resolution.

Function addanchor (parentelement, anchortext, anchorclass) {var element = document. createelement ('A'); parentelement. appendchild (element); element. innerhtml = anchortext; element. classname = anchorclass ;}

Solution

It is very simple. We only need to put the insert element operation at the end of the operation, we can re-parse it only once.

 
Function addanchor (parentelement, anchortext, anchorclass) {var element = document. createelement ('A'); element. innerhtml = anchortext; element. classname = anchorclass; parentelement. appendchild (element );}

However, if we want to insert many hyperlinks into one element, there is still a problem with this practice: Every time we insert a hyperlink, we still need to trigger a re-resolution. The next solution can solve this problem.

Solution 4: create a group of elements through the documentfragment object

This solution allows us to create and insert many elements and only trigger re-resolution once. To achieve this, the so-called document fragment object (documentfragment) is used ). We first create a document fragment object outside the DOM (so that it does not need to be parsed or rendered), and then we create many elements in the document fragment object, finally, we put all the elements in this File Fragment object in the DOM at a time to trigger re-resolution only once.

Requirement

We need to write a function and add 10 hyperlinks to a specified element. If we simply insert 10 hyperlinks to the element, 10 re-resolution will be triggered.

 
Function addanchors (element) {var anchor; For (VAR I = 0; I <10; I ++) {anchor = document. createelement ('A'); anchor. innerhtml = 'test'; element. appendchild (Anchor );}}

Solution

To solve this problem, we need to first create a document fragment object, and then insert each newly created hyperlink into it. When we use the appendchild command to insert a document fragment object to a specified node, all the child nodes of this document fragment object will be inserted into the specified Element together, in addition, you only need to trigger the re-resolution once.

 function addanchors (element) {var anchor, fragment = document. createdocumentfragment (); For (VAR I = 0; I <10; I ++) {anchor = document. createelement ('A'); anchor. innerhtml = 'test'; fragment. appendchild (Anchor);} element. appendchild (fragment) ;}
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.