最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why is appending to an element not yet in the DOM faster than using a javascript Fragment? - Stack Overflow

programmeradmin4浏览0评论

Consider these three versions of appending lis to a 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);

Appending to an element 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 appending to a DOM element held in memory faster than appending to a Fragment? Since fragment was created for this sole purpose shouldn't it be faster? Are they're any advantages to using a fragment over an element held in memory other than not having to include a top level element before appending?

Check the test output from jsperf:

Consider these three versions of appending lis to a 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);

Appending to an element 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 appending to a DOM element held in memory faster than appending to a Fragment? Since fragment was created for this sole purpose shouldn't it be faster? Are they're any advantages to using a fragment over an element held in memory other than not having to include a top level element before appending?

Check the test output from jsperf: http://jsperf./javascript-fragments-tests

Share asked Jul 22, 2014 at 3:27 agcontiagconti 18.1k17 gold badges84 silver badges118 bronze badges 4
  • Without reference to the underlying code or design, whatever answer you get is guesswork. Mine is that a fragment is a generic container for any DOM element, whereas a UL is quite specific and can only have LI child elements, so there's work that a fragment must do when elements are appended that a UL doesn't. I would rate ±4% as not significant. – RobG Commented Jul 22, 2014 at 3:35
  • Don't worry too hard over micro optimization – Sterling Archer Commented Jul 22, 2014 at 3:36
  • What would make a Fragment faster? (Asking hypothetically what optimizations could be done in a Fragment vs. a regular DOM element) – JKillian Commented Jul 22, 2014 at 3:42
  • @JKillian Its supposed to be a minimal document object thats designed for this exact action. I'm not sure what optimizations they could have used to make this happen. – agconti Commented Jul 22, 2014 at 3:48
Add a ment  | 

2 Answers 2

Reset to default 8

It is a bit more work to insert multiple children from a document fragment (particularly when your test has 200 children) than it is to insert a single parent <ul> tag.

So, with the fragment, you're reparenting 200 <li> elements from the fragment to your <ul> tag in the DOM.

With your last code block, you're just reparenting the one <ul> tag by inserting it into the DOM.

So, in your particular example, using the document fragment creates more work for the insertion into the DOM than the way you run your last example that just has to insert the single <ul> tag.


The fragment has its tactical advantages when you want to keep track of a whole bunch of elements at the same level and then insert them with one line of code and you the parent is already in the DOM. But, it isn't always the fastest way to do things vs. a scenario where you can collect all the items out of the DOM at the same level under their actual parent node and then insert just that parent node.

My speculation is...

For Naive version. The loop when appending elements in the DOM gets bigger and longer. As more elements are loaded in the ul tag existing in the DOM the longer it takes to process the succeeding elements to be appended. This one takes longer because you are modifying a tag that already exists in the DOM.

For Javascript Fragment The fragment is non-existent in the HTML document yet and is only appended to ul after inserting a series of li in the fragment. There is only backend processing that is happening in the loop part then inserts the fragment that contains the multiple lis in the DOM. and ofcourse, since the ul is existing in the DOM there's still a loop involved because it takes some time to adopt the child.

For appending to an element not yet in DOM. This one mostly works on the backend and makes the UI interpreter exert less effort since it's like adding another paper on top of a pile of papers(Everything was worked on the paper to be added on top of the pile of papers).

My explanation might not be accurate but at least I'm sharing an idea. This has been one of the biggest problems of us Game developers.

发布评论

评论列表(0)

  1. 暂无评论