1

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?

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
Nishant Srivastava
  • 449
  • 2
  • 7
  • 18
  • 1
    I don't think either approach is better than the other -- it boils down to readability and comfort level. Especially now that there's the new string concatenation, it's a lot cleaner than it was to do string -> HTML than in the past. I prefer the `document.createElement()` approach, but that's just where my comfort level is – Doug Apr 10 '18 at 16:51
  • Note that `
    ${arr[idx].title}
    ` could be vulnerable to XSS (if the `title` is coming from user input).
    – Ionică Bizău Apr 10 '18 at 16:55
  • this is explained here: https://stackoverflow.com/questions/45540613/how-document-fragment-works/70841617#70841617 – Yilmaz Jan 24 '22 at 23:33

2 Answers2

2

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);
Community
  • 1
  • 1
zer00ne
  • 41,936
  • 6
  • 41
  • 68
0

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!

Rantanen
  • 156
  • 5