var mysite = {
    'url': "http://www.ajaxweb20.net",
    'author': "Giuseppe Raso",
    'xhtmlValid': true,
    'cssValid': true
}
Home > Blog

Archive for the ‘Javascript’ Category

Creare elementi: DOM o innerHTML?

Giovedì, Febbraio 7th, 2008

Una delle dispute più frequenti nel mondo di Javascript è quella tra chi sostiene che il DOM sia il modo più sicuro per creare e appendere nuovi elementi e chi invece crede che la velocità di innerHTML sia un buon motivo per non utilizzare gli standard.

Chi ha ragione quindi? Il vero problema è proprio questo: tutti e due.

I metodi standard come createElement e cloneNode hanno il pregio di funzionare sempre e comunque senza dare particolari errori ( al contrario ci sono casi in cui innerHTML non funziona come ci si aspetterebbe ).
Ed essendo standard è pressoché certo che tutti i browser li supporteranno anche in futuro.

Il rovescio della medaglia è che i metodi del DOM sono il doppio se non il triplo più lenti di innerHTML.

Cosa scegliere quindi? Purtroppo non si può dare una risposta precisa; in teoria sarebbe bello poter usare sempre i metodi DOM, ma mettiamo il caso in cui riceviamo del markup html da una chiamata ajax. Visto che questo viene ricevuto sotto forma di testo è molto più pratico ed enormemente più performante utilizzare innerHTML invece che fare il parsing della stringa ricevuta. Persino le librerie e i framework più famosi infatti utilizzano innerHTML.

Ove sia possibile utilizzare il DOM è bene tenere a mente tre principi base per velocizzare lo script:

  1. Possiamo appendere elementi anche a elementi che ancora non sono ancora stati appesi nel documento.
  2. Ogni volta che si appendono uno o più elementi il browser è costretto a ricalcolare la visualizzazzione della pagina. Per questo motivo è molto meglio appendere più elementi in una volta sola piuttosto che appenderli ad uno ad uno.
  3. La funzione cloneNode è più veloce di createElement.

Giusto per fare un esempio vediamo uno script che non segue questi tre principi e uno che invece li mette in pratica.

Script meno performante:

var tbody = document.getElementById("tb1"), //tb1 e’ un tbody
    tr,
    td;
    for(var i = 0; i!=10; i++) {
        tr = document.createElement("tr");
        tbody.appendChild(tr);
        for(var g = 0; g!=100; g++) {
            td = document.createElement("td");
            tr.appendChild(td);
            td.appendChild(document.createTextNode("A"));
        }
    }

Script più performante:

var tbody = document.getElementById("tb2"), //tb2 e’ un tbody
    parent = tbody.parentNode,
    trbase = document.createElement("tr"),
    tdbase = document.createElement("td");
    tdbase.appendChild(document.createTextNode("A"));
    parent.removeChild(tbody);
for(var i = 0; i!=10; i++) {
    tr = trbase.cloneNode(false);
    for(var g = 0; g!=100; g++)
         tr.appendChild(tdbase.cloneNode(false));
         tbody.appendChild(tr);
}
parent.appendChild(tbody);

Facendo un pò di esperimenti ho potuto constatare come il secondo script sia circa 6 volte più veloce del primo, forse addirittura più veloce dello stesso innerHTML.
Da notare che a ciò contribuisce il fatto di avere rimosso il tbody dal documento prima di avergli appeso elementi.