Pregunta

Tengo una pregunta sobre la velocidad de la página y la optimización del código.Tengo una página que se completa casi al 100% mediante llamadas AJAX.Mi pregunta es:¿Es más rápido para mí codificar varios divs, spans, lo que sea vacíos en el HTML de la página y luego completar esos elementos usando javascript?¿O es más rápido crear estos elementos en javascript e insertarlos y agregarlos?Tampoco estoy seguro de si HAY una gran diferencia.Por lo tanto, cualquier ayuda/consejo en esta área sería muy apreciado.

¿Fue útil?

Solución

Hace un par de años, hice un experimento en esto. Es mucho más rápido asignar al innerHTML propiedad de un elemento para crear una estructura compleja que el uso de repetidos createElement appendChild insertBefore etc. llamadas. He desenterrado la publicación que hice al respecto (a Prototype & script.aculo.us Lista de correo); abajo.

Recuerda que analizar html y hacerlo rápidamente es Lo que hacen los navegadores, y están muy optimizados para hacerlo. Si asigna una cadena con una estructura HTML compleja en un elemento de contenedor innerHTML propiedad, estás haciendo una Viaje desde la capa JavaScript a la capa de renderizado del navegador, después de lo cual el código de análisis y representación del navegador puede proceder ininterrumpido.

Por el contrario, si está construyendo esa estructura compleja que usa la API DOM, no solo hay muchos viajes de capa cruzada (JavaScript -> navegador -> JavaScript), sino que el navegador también tiene que trabajar con el DOM API en lugar de sus estructuras internas.

En consecuencia, generalmente vale la pena mirar un motor de plantilla de JavaScript bien escrito (si desea hacer este lado del cliente). Estos generalmente "compilarán" la plantilla una vez en una forma fácilmente procesada, y durante el procesamiento de un conjunto de datos en particular, utilizarán trucos como construir la cadena como fragmentos en una matriz a través de Array#push, y luego obtener el resultado final a través de Array#join pasar "" como el separador. Para cuerdas grandes, eso puede ser más rápido que la concatenación de cadenas, aunque si es (y en qué medida) es muy Dependiente de la implementación (Spidermonkey de Firefox vs. Chrome's V8 vs. IE's JScript), a diferencia del innerHTML vs. Dom Thing, que solo varía en cómo mucho Más rápido es.

Aquí está la lista de correo Mensaje de un par de años hace que estaba hablando (diciendo básicamente lo que digo arriba; wow, fue hace dos años), Aquí está el Pastie se refiere a, aquí está eso copiado a JSBin, y finalmente ... aquí está el código: (Tenga en cuenta que el código es no Destinado a ser una cosa de belleza y una alegría para siempre, fue un truco rápido ... Sin embargo, sí, yeesh, me gustaría pensar que hacía algo un poco mejor ahora, dos años después).

Puede valer la pena convertir esto en algo que funcionará jsperf. No hay tiempo para hacer eso ahora, me 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>

Otros consejos

Siempre será más lento usar JavaScript para hacer esto porque se ejecuta en la parte superior de la carga de la página, en lugar de con ella, como lo haría agregar elementos al HTML. Sin embargo, también podría decir que la carga real de la página es menor (aunque no significativamente) sin tener los elementos en HTML.

Sin embargo, el otro punto es que JavaScript es bastante malo en la recolección de basura, por lo que si está haciendo un montón de llamadas DOM, eventualmente comenzará a sumar en su potencia de procesamiento.

Además, también está interesado en mantener un sitio web semántico, ¿son las etiquetas necesarias? ¿Se degrada con gracia sin JavaScript? Etc., etc. Depende del ángulo que desee tomar, supongo.

Si está creando muchos elementos, internalHTML puede ser mucho más rápido; sin embargo, no forma parte del estándar DOM oficial (aunque es ampliamente compatible).Mi recomendación sería presentar la página con un diseño esqueleto, incluyendo todo el HTML que sea posible en la página misma, y ​​luego tomar referencias a partes relevantes de la página e ingresar los valores con métodos DOM estándar.

Esto debería ser razonablemente rápido, mantendrá la presentación y la lógica separadas y probablemente terminará siendo más flexible en el caso de futuros cambios o rediseños del sitio.

Modificar innerHTML en lugar de usar métodos DOM.

De acuerdo a esto Punto de referencia de W3C DOM VS InnerHTML En QuirksMode, parece que todos los navegadores probados están mucho Más rápido en HTML que Dom.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top