'Which is better to use : doucment fragment or string concatenation while appending html to dom

I have to append list of cards to dom.

html

<div class="card">  
   <div class="card-title">Card 1</div>
   <div class="card-subtext">This is card 1</div>
</div>

js

 let htmlString = '';
 for(let i = 0 ; i < arr.length ; i ++){
   htmlString += `<div class="card">  
   <div class="card-title">${arr[idx].title}</div>
   <div class="card-subtext">${arr[idx].text}</div>
   </div>`;
 }

 document.getElementByID('card-container').innerHTML = htmlString;

where arr is an array of card objects.

It is a good practice to do it this way? (Please note I don't want to use template library).

Or should I use document fragments to achieve the same? If yes, how would it improve the performance?



Solution 1:[1]

I suggest one thing above all:

Change the DOM sparingly. For every addition/removal to the DOM invokes a reflow of the page. The most efficient and fastest way to add elements to the DOM is to create the elements, do all of the necessary modifications and appending before adding to the DOM. Then append all of the elements onto a DocumentFragment. Appending the docFrag to the DOM takes one clean addition to the DOM rather than multiple times.

So .createDocumentFragment() is by far the best as it is demonstrated here at jsPerf. Below are 2 demos:

  1. Demo 1 demonstrates the creation of elements (.createElement()), and appending (.appendChild()) them to a DocumentFragment (.createDocumentFragment())

  2. Demo 2 demonstrates how to attach a string to a DocumentFragment node made by .createContextualFragment().

Demo 1

var frag = document.createDocumentFragment();

var list = document.createElement('ol');
list.className = 'main-list';

for (let i = 0; i < 3; i++) {
  var item = document.createElement('li');
  item.textContent = 'ITEM';
  item.className = 'item'+i;
  list.appendChild(item);
}

frag.appendChild(list);

document.body.appendChild(frag);

Demo 2

var str = `<ol class="main-list"><li class="item0">ITEM</li><li class="item1">ITEM</li><li class="item2">ITEM</li></ol>`;
var node = document.createRange();
var frag = node.createContextualFragment(str);
document.body.appendChild(frag);

Solution 2:[2]

I believe you shouldnt worry so much about performance unless you are performing a bazillion of them.

Here are some other threads with more info about this:

javascript document.createElement or HTML tags

And this might help you out:

https://stackoverflow.com/a/2305677/8004150

(Short: while concatenating, you are rebuilding the whole node, which might be slower)

Premature optimization is the root of all evil, some may say. Worry about readability, first!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Rantanen