Questo Post prende spunto dall'articolo di John Resig che tratta i DOM DocumentFragments.
I DOM DocumentFragments sono dei contenitori lightweight (letteralmente "peso-leggero" cioe' semplificati,leggeri)che possono contenere dei nodi del Document Object Model (DOM).
Fanno parte delle specifiche ufficiali "DOM 1", quindi sono supportati nei browser recenti (a partire ad esempio da IE6).
Ma perche' possono diventare utilissimi ad uno sviluppatore di web applications?
Osservando meglio le specifiche si nota che:
"Furthermore, various operations -- such as inserting nodes as children of another Node -- may take DocumentFragment objects as arguments; this results in all the child nodes of the DocumentFragment being moved to the child list of this node"
ovvero cio' significa che se prendiamo un set di nodi del DOM e lo aggiungiamo ad un frammento (fragment) allora possiamo aggiungere il frammento al documento, invece di aggiungere ogni nodo singolarmente.
Nel far questo si ottiene una migliore performance complessiva, avendo a disposizione anche il metodo cloneNode nell'oggetto DocumentFragments. Questo perche' e' meno costoso aggiungere i nodi al frammento, essendo un oggetto molto piu' piccolo dell'intero DOM che invece ad ogni inserimento deve essere "risistemato".
Supponiamo di avere un blocco di nodi DOM che vogliamo inserire in un semplice documento:
var elems = [
document.createElement("hr"),
text( document.createElement("b"), "Links:" ),
document.createTextNode(" "),
text( document.createElement("a"), "Link A" ),
document.createTextNode(" | "),
text( document.createElement("a"), "Link B" ),
document.createTextNode(" | "),
text( document.createElement("a"), "Link C" )
];
function text(node, txt){
node.appendChild( document.createTextNode(txt) );
return node;
}
Se vogliamo aggiungere questi nodi nel nostro documento probabilmente lo faremmo nel modo tradizionale: con un ciclo che scorre i nodi, li clona individualmente (cosicche' possiamo continuare ad aggiungerli attraverso tutto il documento):
var div = document.getElementsByTagName("div");
for ( var i = 0; i < div.length; i++ ) {
for ( var e = 0; e < elems.length; e++ ) {
div[i].appendChild( elems[e].cloneNode(true) );
}
}
DocumentFragments AppendInvece quando consideriamo l'uso dell'oggetto DocumentFragments possiamo subito vedere una diversa struttura. Per iniziare aggiungiamo tutti i nostri nodi nel frammento stesso, costruito usando il metodo createDocumentFragment.
Poi il punto interessante arriva quando e' ora di inserire effettivamente i nodi dentro il documento: dobbiamo solo chiamare appendChild e cloneNode una volta sola per tutti i nodi!
var div = document.getElementsByTagName("div");
var fragment = document.createDocumentFragment();
for ( var e = 0; e < elems.length; e++ ) {
fragment.appendChild( elems[e] );
}
for ( var i = 0; i < div.length; i++ ) {
div[i].appendChild( fragment.cloneNode(true) );
}
Facendo qualche misurazione su una pagina di demo si ottiengono risultati analoghi a questi:Browser Normal (ms) Fragment (ms)
Firefox 3.0.1 90 47
Safari 3.1.2 156 44
Opera 9.51 208 95
IE 6 401 140
IE 7 230 61
IE 8b1 120 40