Creare elementi: DOM o innerHTML?
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:
- Possiamo appendere elementi anche a elementi che ancora non sono ancora stati appesi nel documento.
- 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.
- 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:
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:
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.
Tags: DOM, innerHTML, Javascript