Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"virtual" dom manipulation?

I know that doing multiple dom manipulations is bad as it forces multiple repaints.

I.e:

$('body').append('<div />')
         .append('<div />')
         .append('<div />')
         .append('<div />');

Instead a better practise is apparently:

$('body').append('<div><div></div><div></div><div></div><div></div></div>');

but I am curious about virtual manipulation

I.e:

$('<div />').append('<div />')
            .append('<div />')
            .append('<div />')
            .append('<div />')
            .appendTo('body');

is it still bad, obviously there will be some overhead from calling a function several times, but is there going to be any severe performance hits?


Reason I am asking is this:
var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];

var element = $('<div />');

$.each(divs, function(i,o){
    element.append($('<div />', o));
});

$('body').append(element);

Imagine that the divs array has come from an database table describing a form (ok, i'm using div's in the example, but it can be easily replaced with inputs) or something similar.

or with the "recommended" version we have:

var divs = [
    {text: 'First',  id: 'div_1', style: 'background-color: #f00;'},
    {text: 'Second', id: 'div_2', style: 'background-color: #0f0;'},
    {text: 'Third',  id: 'div_3', style: 'background-color: #00f;'},
    {text: 'Fourth', id: 'div_4', style: 'background-color: #f00;'},
    {text: 'Fifth',  id: 'div_5', style: 'background-color: #0f0;'},
    {text: 'Sixth',  id: 'div_6', style: 'background-color: #00f;'}
];

var element = '<div>';

$.each(divs, function(i,o){
    element += '<div ';

    $.each(o, function(k,v){
        if(k != 'text'){
            element += k+'="'+v+'" ';
        }            
    });

    element += '>'+o.text+'</div>';

});

element += '</div>';

$('body').append(element);
like image 636
Hailwood Avatar asked Nov 02 '12 23:11

Hailwood


1 Answers

Firstly, although it is great to read about potential performance hits like this you should always start by measuring to see if you even have a problem.

If you cannot perceive a problem, write the most readable code.

If you can perceive a problem, measure, change and measure.

Having said all this, the last example you have posted involves elements that are not yet written to the DOM, so there would be no repaint until the appendTo adds the elements to the DOM.

I would be very surprised if you could capture a difference in speed between second and third example - and quite surprised if you could see any major difference between any of them.

like image 99
Fenton Avatar answered Oct 06 '22 08:10

Fenton