In terms of performance, is it better to have 20 elements (with their children) in the DOM tree or everything stored in a Javascript object?
Case 1:
<html>
<body>
<div id='el1'>
<span>...</span>
...
</div>
<div id='el2'>
<p>...</p>
...
</div>
<div id='el3'>
<img src="" alt="" />
<br/>
</div>
<div id='el4'>
<section></section>
...
</div>
...
</body>
</html>
Case 2:
var OBJ = {};
OBJ.el1 = $("<div id='el1'><span>...</span>...</div>");
OBJ.el2 = $("<div id='el1'><p>...</p>...</div>");
OBJ.el3 = $("<div id='el1'><img src="" alt="" /><br/>...</div>");
OBJ.el4 = $("<div id='el1'><section></section>...</div>");
....
My application should only show one of these elements at once. Will it perform better if I just leave them in DOM tree and change their style, or is it preferably to store them in a Javascript object and remove and append them when needed?
How could I test it?
@edit Extra info to consider:
1- all elements were written in the HTML document and then removed and stored in javascript objects when page was loaded.
2- Everytime the active element changes, I have change the DOM structure by removing the current active element and then appending the new one to it.
@EDIT 2: after some tests
The idea is: someone will write the HTML elements to DOM and then Javascript must show/hide only one of these elements at once. These elements have their own children. It may be a Full Page website or a Web App.
I created 2 test cases:
1- Elements will be removed and then re-appended several times by Javascript. So they will be stored in a Javascript object until it's summoned
2- Elements will be in DOM, I'll hide and show them (jQuery functions, but further tests will change the CSS directly) when needed.
<html>
<head>
<script src='https://code.jquery.com/jquery-1.11.3.min.js'></script>
</head>
<body>
<!-- I USED 15 ELEMENTS IN MY TEST, BUT THE CODE IS TOO LONG -->
<script>
var OBJ1 = {};
var OBJ2 = new Array();
var ACTIVE;
var BODY = $(document.body);
var T1, T2, DELTA;
$(function(){
T1 = new Date().getTime();
/*
//TEST 1: Javascript
var _this,id;
$('div').each(function(){
_this = $(this);
id = _this.attr('id');
OBJ1[id] = _this;
_this.remove();
});
var c;
for (var i = 0; i < 10000; i++) {
for(var k in OBJ1){
c = OBJ1[k];
if(ACTIVE) ACTIVE.remove();
BODY.append(c);
ACTIVE = c;
}
}*/
//TEST 2: DOM
var _this,id;
$('div').each(function(){
_this = $(this);
id = _this.attr('id');
OBJ2.push(id);
});
var c;
for (var i = 0; i < 10000; i++) {
for(var k=0,l=OBJ2.length;k<l;k++){
c = $('#'+OBJ2[k]);
if(ACTIVE) ACTIVE.hide();
c.show();
ACTIVE = c;
}
}
T2 = new Date().getTime();
DELTA = T2 - T1;
console.log('It took '+DELTA+' milliseconds');
});
</script>
</body>
I created 5 generic elements with some Lorem Ipsum and Lorem Pixel content and them copied/pasted them 3 times, making 15 1st-level elements.
For 1000 times I hide and revealed each one of the 15 elements. Ran the test 3 times each.
Case 1 (winner so far): 5.2s, 4.75s, 4.85s
Case 2: 21.5s, 21.5s, 20s
@edit 3: changing Case 2 method
Changing the second case from hide()/show() to css() makes a high increase in performance.
//TEST 2: DOM
var _this,id;
$('div').each(function(){
_this = $(this);
_this.css('display','none');
id = _this.attr('id');
OBJ2.push(id);
});
var c;
for (var i = 0; i < 15000; i++) {
for(var k=0,l=OBJ2.length;k<l;k++){
c = $('#'+OBJ2[k]);
if(ACTIVE) ACTIVE.css('display','none');
c.css('display','block');
ACTIVE = c;
}
}
Also increase the loop to 15k.
Case 1: Around 6.5s
Case 2: Around 2.5s
imgand so you may want to consider whether you want to preload the image resource. If you inject theimginto the DOM with script then it won't start loading until that the element is added to DOM.css('display')to be much faster thanshow()/hide(). Here is a perf test I was playing with; it's a simpler case than yours but still emphasizes that the show/hide withcss()works better in this case than removing and appending. See jsperf: jsperf.com/dynamic-dom-performance