jQuery animate() y rendimiento del navegador

7 minutos de lectura

Tengo algunos elementos que muevo por la página muy lentamente. Esencialmente, estoy disminuyendo el margen izquierdo de dos imágenes en un lapso de 40 segundos más o menos.

Visualmente, está funcionando maravillosamente. Sin embargo, mi procesador salta a un 50 % de uso durante las animaciones. Esto tampoco es específico de un solo navegador, es lo mismo en Safari3 y Firefox3. Si tengo ambos navegadores ejecutando la página, mi CPU está gritando con un uso de aproximadamente el 95%.

Estoy usando jQuery 1.3. Ambas animaciones están sucediendo simultáneamente. No hay Flash en la página. Si comento el código (elimino la animación) y actualizo la página, mi procesador vuelve inmediatamente al uso normal.

Espero no tener que recurrir a Flash, pero incluso ver programas en Hulu.com no aumenta mi CPU de esta manera.

¿Pensamientos?

jQuery animate y rendimiento del navegador
Alconja

Sé que esta es una pregunta anticuada y Tim proporcionó una excelente respuesta, pero pensé que debería publicar una actualización para cualquiera que busque una solución a este problema, ya que ahora hay una manera más simple…

A partir de jQuery 1.4.3 puede establecer el intervalo que usa jQuery’s animate directamente a través del jQuery.fx.intervalo propiedad. Así que simplemente puedes hacer algo como:

jQuery.fx.interval = 50;

  • esto establece un intervalo global para todas las animaciones. ¿Por casualidad sabes cómo se puede establecer un intervalo para una sola animación específica?

    – Hans

    04 jun.

  • @Marcel: no que yo sepa, creo que todas las animaciones comparten el mismo temporizador interno, pero podría estar equivocado …

    – Alconja

    05 jun.

  • 24 fps, la velocidad a la que se realizan muchas filmaciones, parece representar un buen punto de partida para jugar con este número. Entonces, 1000ms / 24fps = ~42

    – Matt Parkins

    12 nov.

  • El valor predeterminado es 13 (milisegundos)

    – árbol bendy

    23 abr.


Creo que la forma en que funciona jQuery animate() es que utiliza un temporizador que periódicamente activa e invoca una función que actualiza el DOM para reflejar el estado de la animación. Por lo general, las animaciones son relativamente cortas y pueden cubrir una buena cantidad de espacio en la pantalla, por lo que sospecho (sin confirmar) que el temporizador caduca y se reinicia a una velocidad bastante alta para generar una animación fluida. Dado que su animación lleva mucho tiempo, es posible que pueda modificar la función de animación para que la velocidad a la que avanza la animación se pueda establecer a través de una opción. En su caso, solo necesitaría actualizar cada 250 ms aproximadamente, ya que está cubriendo aproximadamente 3-4 píxeles por segundo, aproximadamente.

  • Dado que la animación ya es lenta, me pregunto si eso haría que la animación avanzara de una manera irregular. Tratando de evitar que la página parezca un viejo juego de Atari. ja ja. No sé, ¿crees que Flash estaría mejor equipado para esto?

    – Jeremy Rickets

    19 ene.

  • No. Tendrías que hacer que toda la página parpadee. IIRC, no puedes tenerlo como elemento de fondo

    – Stingy Jack

    19 ene.

  • Este bit estaría en el área de encabezado del sitio. Así que creo que poner una película flash detrás del contenido principal podría ser una opción. Sin embargo, no sé nada sobre la creación de una película Flash. Trabajo mucho con ellos, pero no soy autor de ellos. :-/

    – Jeremy Rickets

    19 ene.

  • Aceptar este debido a la descripción detallada de la naturaleza del problema y la solución sugerida. ¡Gracias a todos! La primera pregunta de Stackedoverflow fue un gran éxito. Volveré aquí para ayudar a otros también.

    – Jeremy Rickets

    19 ene.

  • Si no lo necesita como fondo, Flash es una opción.

    – Stingy Jack

    20 ene.

La gente ha mencionado la ralentización de la frecuencia de actualización de jQuery. Puede anular la función de temporizador en jQuery 1.4 con este archivo (jquery.animation-fix.js):

function now() {
    return (new Date).getTime();
}
jQuery.fx.prototype.custom = function( from, to, unit ) {
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }

    t.elem = this.elem;

    if ( t() && jQuery.timers.push
        //timerId = setInterval(jQuery.fx.tick, 13);
        jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 2050);
    }
}

Así que modifica la línea con esto en ella.

jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 50);

Cambie el 50 al intervalo que desee. Eso es en milisegundos (ms)

Si guarda este código en un archivo diferente, puede adjuntarlo así:

<script src="https://stackoverflow.com/js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="/js/jquery.animation-fix.js" type="text/javascript"></script>

  • Estaba pensando, me pregunto si podría agrupar esto en un complemento que establezca setInterval por animación. Como, podrías agregar un parámetro a api.jquery.com/animate eso cambió el intervalo para ese elemento. mmm.

    – Jeremy Rickets

    12 jun.

  • ¡Tim, esto es exactamente lo que estaba buscando! Amo tu trabajo 🙂

    –David Meister

    28 ago.

  • Nota para cualquiera que use esta solución: Esta funcionalidad ahora está integrada en jQuery, a partir de 1.4.3. (+1 por una gran solución para pre-1.4.3).

    – Alconja

    08 dic. 10 a las 21:46

jQuery animate usa la función de javascript ‘setInterval’ para actualizar los objetos cada pocos milisegundos. Desafortunadamente, el intervalo en jQuery es por defecto ’13ms’. Eso es 76 actualizaciones cada segundo. Demasiado para animaciones tan lentas y medianas.

Los 13 ms están codificados en jQuery. Entonces puede cambiar directamente este valor en jQuery.js, solo. Si solo tienes las nubes lentas, puedes llegar hasta los 100 ms. Si también tiene algunas animaciones más rápidas, debe establecerlo en 50.

Puede cambiar el parámetro para setInterval(); en la función personalizada. ‘jQuery.fx.prototype { … personalizado: función() { … } … }’

Las animaciones involucran operaciones de bucle, y esas realmente harán que la CPU se agote sin importar qué.

No sé qué tan fácil es hacerlo con jQuery, pero lo que debe suceder es que la animación necesita consumir menos ciclos. O hace que el ani sea un poco más irregular (la visualización no es tan suave), el bucle debe optimizarse o reduce el trabajo del ani.

40 segundos? ¿No es un poco largo para una animación? Pensé que se suponía que eran un poco más inmediatos que eso.

  • La animación es un sutil movimiento de nubes en la parte superior de una página. Comienzan en una posición aleatoria y se mueven lentamente hacia la izquierda.

    – Jeremy Rickets

    19 ene.

jQuery animate y rendimiento del navegador
persona

Acabo de ver el rendimiento de la animación en Scriptaculous y encontré picos de CPU similares: aproximadamente un 50 % para IE, un rendimiento ligeramente mejor (16-30 %) para Firefox, ambos en una PC DuoCore. Dado que tanto JQuery como Scriptaculous funcionan cambiando el CSS subyacente, creo que es seguro decir que cualquier implementación de Javascript será computacionalmente costosa.

Es posible que te quedes atascado con Flash.

  • La animación es un sutil movimiento de nubes en la parte superior de una página. Comienzan en una posición aleatoria y se mueven lentamente hacia la izquierda.

    – Jeremy Rickets

    19 ene.

1642389669 35 jQuery animate y rendimiento del navegador
david meister

Me gusta mucho la respuesta publicada por Tim, aunque necesitaba que esta solución funcionara en un entorno de producción de Drupal 6.

Tengo jQuery 1.3.2 instalado, mediante el uso del módulo de actualización de jQuery, por lo que hay algunas diferencias entre lo que estoy usando y jQuery 1.4 para el que está diseñada la corrección de Tim.

Seguir las instrucciones de Tim me llevó al 90% del camino, solo tuve que poner mi límite de pensamiento durante 10 minutos para encontrar este código en su lugar.

los valores de temporizador de 25 a 33 parecen funcionar mucho mejor que 13 ms para animaciones de velocidad media, como imágenes de fondo que se desvanecen.

var timerId;

function now() {
    return (new Date).getTime();
}

jQuery.fx.prototype.custom = function( from, to, unit ) {
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) {
        return self.step(gotoEnd);
    }

    t.elem = this.elem;

        if ( t() && jQuery.timers.push
    timerId = setInterval(function(){
        var timers = jQuery.timers;

        for ( var i = 0; i < timers.length; i++ )
            if ( !timers[i]() )
                timers.splice(i--, 1);

        if ( !timers.length ) {
            clearInterval( timerId );
            timerId = undefined;
        }
    }, 25);
}
};

.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad