Why is adding an element not yet in the DOM faster than using a javascript fragment?

Consider these three versions of adding li to ul :

Naive version (20% slower):

 var ul = document.getElementById('targetUl'); for (var i = 0; i < 200; i++) { var li = document.createElement('li'); li.innerHTML = Math.random(); ul.appendChild(li); } 

Using a JavaScript fragment (4% slower):

 var ul = document.getElementById('targetUl'), fragment = document.createDocumentFragment(); for (var i = 0; i < 200; i++) { var li = document.createElement('li'); li.innerHTML = Math.random(); fragment.appendChild(li); } ul.appendChild(fragment); 

Adding to an element is not yet in the DOM (1.26% faster):

 var ul = document.createElement('ul'), div = document.getElementById('targetDiv'); for (var i = 0; i < 200; i++) { var li = document.createElement('li'); li.innerHTML = Math.random(); ul.appendChild(li); } div.appendChild(ul); 

Why is adding to a DOM element stored in memory faster than adding to a Fragment ? Since Fragment was created for this single purpose, shouldn't it be faster? Are they advantages of using Fragment over an element stored in memory, in addition to not having to include a top-level element before adding it?

Check test result from jsperf: http://jsperf.com/javascript-fragments-tests

+6
source share
2 answers

It’s a bit more work to insert several children from a document fragment (especially when your test has 200 children) than to insert one parent <ul> .

So, with the help of the fragment, you repeatedly clear 200 <li> elements from the fragment to your <ul> in the DOM.

With your last block of code, you simply rewrite one <ul> by inserting it into the DOM.

So, in your specific example, using a document fragment does more work to be inserted into the DOM than how you run your last example, which simply needs to insert a single <ul> .


A fragment has its tactical advantages when you want to track a whole bunch of elements at the same level, and then insert them with one line of code, and the parent is already in the DOM. But this is not always the fastest way to do something against a scenario in which you can collect all the elements from the DOM at the same level under your actual parent node, and then insert that particular parent node.

+7
source

My suggestion...

For the naive version. The cycle when added items in the DOM get bigger and bigger. Since the ul tag that exists in the DOM loads more elements, the more time it takes to process subsequent elements that need to be added. This takes longer because you are modifying a tag that already exists in the DOM.

For a Javascript fragment, the fragment does not yet exist in the HTML document and is added only to ul after inserting the li series into the fragment. There is only backend processing that occurs in part of the loop, and then inserts a fragment containing multiple lis into the DOM. and, of course, since ul exists in the DOM, there is still a loop because it takes some time to accept a child.

To add to an element not yet in the DOM. This basically works on the backend and makes the interface interpreter less effort because it is like adding other paper on top of a pile of papers (everything was processed on paper to be added on top of the pile of papers).

My explanation may be inaccurate, but at least I share the idea. This was one of the biggest problems we had for game developers.

0
source

Source: https://habr.com/ru/post/972628/


All Articles