Domanda

Ho una domanda riguardante la velocità di pagina e l'ottimizzazione del codice. Ho una pagina che è popolata quasi al 100% attraverso le chiamate Ajax. La mia domanda è: è più veloce per me codificare diversi div vuoti, campate, qualunque cosa nell'HTML della pagina, quindi riempire quegli elementi usando JavaScript? Oppure, è più veloce creare questi elementi in JavaScript e inserirli? Non sono sicuro che ci sia nemmeno una grande differenza. Quindi, qualsiasi aiuto/consiglio in questo settore sarebbe molto apprezzato.

È stato utile?

Soluzione

Un paio di anni fa, ho fatto un esperimento su questo. È molto più veloce da assegnare al innerHTML Proprietà di un elemento per creare una struttura complessa di quanto non sia da utilizzare createElement appendChild insertBefore ecc. chiamate. Ho scavato il post che ho fatto al riguardo (al prototipo e script.culo.us List); sotto.

Ricorda che analizzare HTML e renderlo velocemente è Cosa fanno i browser, e sono altamente ottimizzati per farlo. Se si assegna una stringa con una struttura HTML complessa in essa a un elemento del contenitore innerHTML Proprietà, stai facendo uno Viaggio dal livello JavaScript al livello di rendering del browser, dopodiché il codice di analisi e rendering del browser può procedere ininterrottamente.

Al contrario, se stai costruendo quella struttura complessa che utilizza l'API DOM, non solo ci sono molti viaggi a strato di trasversale (javascript -> browser -> javascript), ma il browser deve anche lavorare con il DOM API piuttosto che le sue strutture interne.

Di conseguenza, di solito vale la pena guardare un motore di modelli JavaScript ben scritto (se si desidera fare questo lato client). Questi di solito "compileranno" il modello una volta in una forma facilmente elaborata e durante l'elaborazione per un particolare set di dati, utilizzeranno trucchi come costruire la stringa come frammenti in un array tramite Array#push, e poi ottenere il risultato finale tramite Array#join passando "" come separatore. Per stringhe di grandi dimensioni, può essere più veloce della concatenazione delle stringhe, sebbene sia (e in che misura) molto dipendente dall'implementazione (Spidermonkey di Firefox vs. Chrome's V8 vs. IE's JScript), a differenza del innerHTML vs. dom, che varia solo in come tanto più veloce è.

Ecco la mailing list Messaggio di un paio di anni fa di cui stavo parlando (dicendo sostanzialmente quello che dico sopra; wow, è stato due anni fa), Ecco il pascolo si riferisce a, ecco quello Copiato a JSbin, e infine ... ecco il codice: (Si noti che il codice è non Inteso per essere una cosa di bellezza e gioia per sempre, è stato un rapido hack ... però, yeesh, mi piacerebbe pensare che avrei avuto un po 'di più un po' meglio ora, due anni dopo.)

Potrebbe valere la pena convertirlo in qualcosa su cui funzionerà jsperf. Non c'è tempo per farlo adesso, temo.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style>
#log {
    border-bottom:  1px solid black;
}
#log p {
    margin:     0;
    padding:    0;
}
</style>
<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
<script type='text/javascript'>
document.observe('dom:loaded', function() {
    $('btnDOMDirect').observe('click', useDOMDirect);
    $('btnPrototypeDOM').observe('click', usePrototypeDOM);
    $('btnHTML').observe('click', useHTML);

});

var numRows = 10;
var numCols = 10;

function usePrototypeDOM(evt)
{
    var table;
    var tbody;
    var tr;
    var td;
    var row;
    var col;
    var start;
    var end;

    start = (new Date()).getTime();

    table = new Element('table');
    tbody = new Element('tbody');
    table.appendChild(tbody);
    for (row = 0; row < numRows; ++row) {
        tr = new Element('tr');
        tbody.appendChild(tr);
        for (col = 0; col < numCols; ++col) {
            td = new Element('td');
            td.update('Row ' + row + ', col ' + col);
            tr.appendChild(td);
        }
    }
    $('targetTable').update(table);

    end = (new Date()).getTime();
    log('DOM took ' + (end - start) + 'ms');
}

function useDOMDirect(evt)
{
    var table;
    var tbody;
    var tr;
    var td;
    var row;
    var col;
    var start;
    var end;

    if (Prototype.Browser.IE) {
        alert("DOM direct doesn't work on IE because I used table elements.  Sorry.  The other two work.");
        return;
    }

    start = (new Date()).getTime();

    table = document.createElement('table');
    tbody = document.createElement('tbody');
    table.appendChild(tbody);
    for (row = 0; row < numRows; ++row) {
        tr = document.createElement('tr');
        tbody.appendChild(tr);
        for (col = 0; col < numCols; ++col) {
            td = document.createElement('td');
            td.update('Row ' + row + ', col ' + col);
            tr.appendChild(td);
        }
    }
    $('targetTable').update(table);

    end = (new Date()).getTime();
    log('DOM took ' + (end - start) + 'ms');
}

function useHTML(evt)
{
    var html;
    var row;
    var col;
    var start;
    var end;

    start = (new Date()).getTime();

    html = '<table><tbody>';
    for (row = 0; row < numRows; ++row) {
        html += '<tr>';
        for (col = 0; col < numCols; ++col) {
            html += '<td>Row ' + row + ', col ' + col + '</td>';
        }
        html += '</tr>';
    }
    html += '</tbody></table>';
    $('targetTable').update(html);

    end = (new Date()).getTime();
    log('HTML took ' + (end - start) + 'ms');
}

function log(msg)
{
    var l;
    var p;

    l = $('log');
    if (l) {
        p = new Element('p');
        p.update(msg);
        l.appendChild(p);
    }
}
</script>
</head>
<body>
<input type='button' id='btnDOMDirect' value='DOM Direct' />
<input type='button' id='btnPrototypeDOM' value='Prototype DOM' />
<input type='button' id='btnHTML' value='HTML' />
<div id='log'></div>
<div id='targetTable'></div>
</body>
</html>

Altri suggerimenti

Sarà sempre più lento usando JavaScript per farlo perché funziona in cima al caricamento della pagina, piuttosto che con esso, come aggiungere elementi all'HTML. Tuttavia, si potrebbe anche dire che il carico effettivo della pagina è inferiore (anche se non significativamente) senza avere gli elementi in HTML.

L'altro punto è, tuttavia, JavaScript è piuttosto negativo nella collezione Garbage, quindi se stai effettuando un sacco di chiamate DOM, alla fine inizierà a sommarsi nella tua potenza di elaborazione.

Inoltre c'è anche se sei interessato a mantenere un sito web semantico, sei necessario? Si degrada con grazia senza JavaScript? Ecc. Ecc. Dipende dall'angolo che desideri prendere, suppongo.

Se stai creando molti elementi InnerHTML può essere molto più veloce, tuttavia non fa parte dello standard DOM ufficiale (anche se è ampiamente supportato). La mia raccomandazione sarebbe quella di servire la pagina con un layout di scheletro, incluso il maggior numero possibile di HTML nella pagina stessa, quindi prendere riferimenti alle parti pertinenti della pagina e collegare i valori con metodi DOM standard.

Ciò dovrebbe essere ragionevolmente veloce, manterrà separati la presentazione e la logica e probabilmente finirà per essere più flessibili nel caso di futuri modifiche al sito o riprogettazioni.

Modificare innerHTML invece di usare i metodi DOM.

Secondo questo Benchmark di W3C Dom vs InnerHTML su QuirksMode, sembra che tutti i browser testati lo siano tanto Più veloce su HTML di Dom.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top