DOM operation optimization--DocumentFragment efficiently updates multiple nodes

Preface: The operation of the DOM tree will cause backflow, and DocumentFragment can be added to the DOM tree at one time to reduce the number of backflows and achieve optimization purposes.

1. Basic concepts:

DocumentFragment : It is used as a lightweight version of Document, just like a standard document, storing a document structure composed of nodes.

document: Corresponding to the displayed page, including n elements, once an element inside the document is updated, the interface is updated.

Difference from document: Compared with document, the biggest difference is that DocumentFragment is not a part of the real DOM tree. Its changes will not trigger the re-rendering of the DOM tree and will not cause performance problems.

2. Basic usage:

This interface has no special attributes. Its attributes are inherited from Node and supplement the attributes in the ParentNode interface.

We want to change all the text in li in ul to 123456.

<ul id="fragment_test">
    <li>01</li>
    <li>02</li>
    <li>03</li>
</ul>

The original method:

  • Traverse
  • change

In this way, the document is refreshed three times. If there are many elements to be changed, the document will be refreshed many times.

After using DocumentFragment we can:

  1. Create a fragment.
  2. Take out all the child nodes in ul and save them to fragment (including line breaks).
  3. Modify the value in the fragment.
  4. Insert fragment into ul.
    In this way we only need to update one DOM tree.
    //1、创建fragment
    const fragment = document.createDocumentFragment();
    //2、取出ul中所有子节点取出保存到fragment(包括换行)
    let child;

	//child = ul.firstChild 取出第一个子节点,并将其的值赋值给child,在while循环中并判断值是否为空

    while(child = ul.firstChild){
    
     //一个节点只能有一个父亲
        fragment.appendChild(child);//先将child从ul中移除,添加为fragment子节点
    }
    //3、更新fragment中所有li的文本
    //得到所有的子标签(伪数组)fragment.childNodes
    //工具函数slice()用于将类数组转换为真正的数组
    Array.prototype.slice.call(fragment.childNodes).forEach(node=>{
    
    
        if(node.nodeType === 1){
    
    //元素节点<li>,node.nodeType是节点的类型1:元素节点 3:文本节点
            node.textContent = '123456'
        }
    });
    //4、将fragment插入ul
    ul.appendChild(fragment);

Guess you like

Origin blog.csdn.net/weixin_43690348/article/details/109688047