ECMAScript and DOM are two different islands. Every time a browser accesses each other, it charges a toll, so we need to minimize the toll and minimize DOM interaction with ECMAScript

DOM access and modification

1. Merge multiple temporary changes and finally modify the DOM in a unified manner

function innerHTMLLoop2(){
    let content = ' ';
    for(let i =0; i< 15000; i++){
        content += 'a';
    }
    document.getElementById('temp').innerHTML = content;
}
Copy the code

2. UseinnerHTMLorDOM

In most cases, browsers don’t make much of an efficient difference between innerHTML and DOM, but if you’re updating a large chunk of HTML in a performance-critical operation, use innerHTML instead

3. Clone nodes

Elment.clonenote () replaces document.createElement() and is more efficient than cloning nodes in most browsers

4. HTMLA collection of

The HTML collection keeps this connection with the document, and every time we access the HTML collection, we repeat the query process, even if it’s just to get the number of elements in the collection (that is, to access the length property of the collection)

Optimization:

  • When accessing collection elements, cache them as local variables as possible (e.g., cache the length of the collection in a local variable)
  • Copying a collection element to an array first makes accessing its attributes faster, but copying to an array involves additional destruction, traversing the collection more than once, and therefore requires evaluation under certain conditions

5. Traverse the DOM

  • childrenchildNodes,childrenthanchildNodesBe quick, because white space (text nodes) in HTML source code is not therechildrenIn, but will appear inchildNodesIn the
  • querySelectorAll()This kind ofqueryThe API at the beginning is better thandocument.getElementThis API is fast, especially when we need to process a large number ofCombination queryAnd,querySelectorWhat we get is a static list, anddocument.gelElementWhat you get is a collection of HTML

6. Redraw and rearrange

  • The DOM tree:

For every node in the DOM tree that needs to be displayed, there is at least one corresponding node in the render tree (except for hidden DOM).

  • Render tree:

Nodes in the render tree are called “frames” or “boxes”.

  • Conclusion:
  1. Rearrangement + redraw occurs when a change in the DOM causes the geometry of an element, the DOM is added or removed, the position is changed, the content is changed (replaced by another image of a different size), the browser window is changed, and the page renderer is initialized

  2. Depending on the extent and degree of change, parts of the rendering tree are recalculated (rearranged), but the entire page is also rearranged (e.g. scrollbars appear)

  3. If knowledge changes color etc, then only redraw without rearrangement

  4. Try to avoid using:

    • offsetTop, offsetLeft, offsetWidth, offsetHeight
    • scrollTop, scrollLeft, scrollWidth, scrollHeight
    • clientTop, clientLeft, clientWidth, clientHeight
    • getComputedStyle()

    Because browsers typically optimize their reordering performance by queuing changes and batch reordering. However, these attributes force a refresh requeue and require immediate execution to ensure that the latest values are retrieved. It is therefore best to avoid using the attributes listed above in styling projects. Because they all refresh the render queue, even if you’re retrieving layout information that hasn’t changed recently or isn’t relevant to the latest change.

  5. Minimize redraw and rearrange

Use cssText instead of el.style.borderLeft=1px, for example: “border-left:1px; border-right:2px; padding:5px”

  1. Batch modify the DOM to reduce redrawing and reordering

    Thinking: Elements leave the document flow ==> Apply multiple changes to them ==> bring the element back into the document

    1. (Hide elements, apply changes, redisplay). For example:
    ```js var ul = document.getElementById('mylist'); ul.style.display = 'none'; ul.appendChild(tempNode); ul.style.display = 'block'; ` ` `Copy the code
    1. Use the document fragment document.fragment
    ```js var fragment= document.createDocumentFragment(); fragment.appendChild(tempNode); fragment.appendChild(temp2); var ul = document.getElementById('mylist'); ul.appendChild(fragment); ` ` `Copy the code
    1. Copy the original element to a node out of the document, manipulate the copy, and replace the original element when done
    ```js var old = document.getElementById('mylist'); var clone = old.cloneNode(true); clone.appendChild(temp); old.parentNode.replaceChild(clone, old); ` ` `Copy the code
  2. Cache layout information

// bad
myElement.style.left = 1 + myElement.offsetLeft + 'px'; // Read and write every time, there is a forcible refresh
myElement.style.top = 1 + myElement.offsetTop + 'px';
if(myElement.offsetLeft >=500){
    stopAnimation();
}

// good
var current = myElement.offsetLeft; // Read only once
current++;
myElement.style.left = current + 'px'; // There is only writing, there is no reading, there is no query, so efficiency is greatly improved
myElement.style.top = current + 'px';
if(current>=500){
    stopAnimation();
}

Copy the code
  1. During animation, take the target element out of the document flow to reduce the rearrangement
  • Make use of absolute positioning

7. Less event binding on the DOM

A lot of event binding on the DOM can take a toll on our DOM performance

Classic example: bind event listening on UL, using bubble mechanism, to listen on our LI, rather than bind event listening on 100 or more Li

conclusion

Accessing and manipulating the DOM is an important part of modern browsers

  • Minimize DOM access and handle it on the JS side as much as possible
  • If you want to access a DOM node multiple times, store it in local variables
  • Use faster apis, for examplequerySelectorAllfirstElementChild
  • Try to batch change styles at once, and manipulate DOM trees “offline,” using caches, and reducing the number of times you have to access layout information
  • Use absolute positioning in animation
  • Use event delegates to reduce the number of event handlers