Use of JavaScript document fragments

Keywords: Fragment Javascript

In JavaScript, document fragment is independent of DOM tree and exists in memory. It is a blank document fragment at the beginning of creation. We can use createDocumentFragment to create it

let fragment = document.createDocumentFragment();

The operations on document fragments, including inserting nodes and deleting nodes, have the same API as other DOM elements, but there are some differences

  1. When the elements in the DOM tree are inserted into the document fragment, the elements in the DOM tree are deleted
<body>
    <div id="t1">t1</div>
    <button onclick="insert()">insert</button>
    <script>
        function insert() {
            let frag = document.createDocumentFragment()
            frag.appendChild(document.querySelector("#t1"))
            console.log(frag)
        }
    </script>
</body>

Here, click the button and you will find that the node in the page disappears and appears in the printed frag

2. When we insert the document fragment into the DOM tree, it is not the document fragment, but the descendant element of the document fragment

<body>
    <div id="t1">t1</div>
    <button onclick="insert()">insert</button>
    <script>
        function insert() {
            let frag = document.createDocumentFragment()
            let p = document.createElement('p')
            p.innerHTML = 'p'
            let div = document.createElement('div')
            div.innerHTML = 'div'
            frag.appendChild(p)
            frag.appendChild(div)
            document.querySelector('#t1').appendChild(frag)
        }
    </script>
</body>

Look at the node after clicking the button. It inserts the descendant elements of the document fragment

3. When creating a node, you do not need to pass in the node to be created
As mentioned above, the document fragment created at the beginning is a blank document fragment. When we use document.createElement() to create an element, we need to pass in a string to represent the tagName of the label to be created. However, the document fragment does not need to pass in a signature. In fact, it does not need to, because the last insert is only the descendant node of the document fragment

So, what's the practicability of document fragments? As mentioned above, document fragments are not placed in the DOM tree, but in the memory. This means that when we replace nodes and insert them into the document fragments, there will be no reflow and redraw. If we want to insert a large number of nodes, one by one insertion will inevitably cause a large number of reflow and redraw. First, put them into the document fragments, and then put them into the document Fragment insertion can reduce reflow redraw and improve performance, but can it actually improve? I tested it

<body>
    <button onclick="direct()">Direct insertion</button>
    <button onclick="el()">Put it in the element and insert it</button>
    <button onclick="frag()">Put it in a document fragment before inserting it</button>
    <ul id="test1"></ul>
    <ul id="test3"></ul>
    <script>
        function direct() {
            console.time('Direct insertion')
            for (let i = 0; i < 100000; i++) {
                let li = document.createElement('li');
                li.innerHTML = i;
                document.querySelector('#test1').appendChild(li)
            }
            console.timeEnd('Direct insertion')
        }

        function el() {
            console.time('Put it in the element and insert it')
            let ul = document.createElement('ul');
            for (let i = 0; i < 100000; i++) {
                let li = document.createElement('li');
                li.innerHTML = i;
                ul.appendChild(li)
            }
            document.body.appendChild(ul)
            console.timeEnd('Put it in the element and insert it')
        }

        function frag() {
            console.time('Put it in a document fragment before inserting it')
            let frag = document.createDocumentFragment()
            for (let i = 0; i < 100000; i++) {
                let li = document.createElement('li');
                li.innerHTML = i;
                frag.appendChild(li)
            }
            document.querySelector('#test3').appendChild(frag)
            console.timeEnd('Put it in a document fragment before inserting it')
        }
    </script>
</body>

After the test, it was found that there was little difference in the printing time, and sometimes it took longer to put in the document fragments

Therefore, performance optimization is only theoretical, and there are many factors that affect performance

Published 178 original articles, won praise 12, visited 30000+
Private letter follow

Posted by pouncer on Sun, 26 Jan 2020 21:10:30 -0800