Alternativa a SetInterval y SettimeOut -- javascript campo con memory-management campo con datetime campo con animation camp codereview Relacionados El problema

Alternative to setInterval and setTimeout


17
vote

problema

Español

javascript's class BookPresenter: BookModelObserver, BookViewObserver { let bookModel: BookModel var bookView: BookView init(model: BookModel, view: BookView) { self.bookModel = bookModel self.bookView = bookView self.bookModel.observer = self self.bookView.observer = self let book = self.model.currentBook self.bookView.setData(book) } } 4 y class BookPresenter: BookModelObserver, BookViewObserver { let bookModel: BookModel var bookView: BookView init(model: BookModel, view: BookView) { self.bookModel = bookModel self.bookView = bookView self.bookModel.observer = self self.bookView.observer = self let book = self.model.currentBook self.bookView.setData(book) } } 5 son malvados y no precisos:

  1. ambos Las funciones tienen un retraso de una cantidad variable de milisegundos.

  2. Ambas funciones son muy intensivas en recursos porque se ejecutan varias veces cada segundo.

Una nueva alternativa es class BookPresenter: BookModelObserver, BookViewObserver { let bookModel: BookModel var bookView: BookView init(model: BookModel, view: BookView) { self.bookModel = bookModel self.bookView = bookView self.bookModel.observer = self self.bookView.observer = self let book = self.model.currentBook self.bookView.setData(book) } } 6 , que es menos intensiva en recursos, deshabilitada en la página desenfoque, y no disminuye la velocidad de otras cosas. Esto lo convierte en el sustituto perfecto para un 99887766555443317 99887766555443318 .

Descripción

Estas funciones usan class BookPresenter: BookModelObserver, BookViewObserver { let bookModel: BookModel var bookView: BookView init(model: BookModel, view: BookView) { self.bookModel = bookModel self.bookView = bookView self.bookModel.observer = self self.bookView.observer = self let book = self.model.currentBook self.bookView.setData(book) } } 9 para verificar si ha pasado el tiempo Basado en el tiempo transcurrido calculado a partir de BookView0 . El tiempo aprobado es más preciso que las funciones nativas y teóricamente menos recursos de recursos. Otra ventaja (o desventaja) es que las funciones no se ejecutan en la falta de definición de la página.

Bueno para: animaciones, efectos visuales

Mal para: Temporizadores, Reloj

BookView1

  BookView2  

BookView3

  BookView4  

usage

  BookView5  

Demo

jsfiddle

Preguntas

  1. Normalmente, no escribo funciones dentro de las funciones, pero en este caso es probablemente una buena solución. ¿Qué pasa con las fugas de la memoria si creo cientos de estas funciones basadas en el tiempo?

  2. ¿Hay una mejor solución para borrar esas funciones?

  3. Para animaciones pesadas y múltiples intervalos y tiempos de espera, estaba pensando en activar un solo bucle 9988777666555443326555443326, que verificaría a intervalos y tiempos de espera dentro de una matriz previamente almacenada ... (pero creo No debería haber diferencia si solo hay un BookView7 o múltiple). Entonces, ¿cómo manejan los navegadores esos múltiples BookView8 ?

Nota:

Si el código anterior no funciona aquí es el código original:

  BookView9  
Original en ingles

JavaScript's setTimeout() and setInterval() are evil and not precise:

  1. Both functions have a delay of a varying quantity of milliseconds.

  2. Both functions are very resource-intensive because they execute several times every second.

A new alternative is window.requestAnimationFrame(), which is less resource-intensive, disabled on page blur, and does not slow down other stuff. This makes it the perfect substitute for a modern setTimeout() and setInterval().

Description

These functions use requestAnimationframe() to check if the time has passed based on the elapsed Time calculated from Date.now(). The time passed is more precise than the native functions and theoretically less resource-intensive. Another advantage (or disadvantage) is that the functions are not executed on page blur.

Good for: animations, visual effects

Bad for: timers, clock

RafTimeout

window.rtimeOut=function(callback,delay){  var dateNow=Date.now,      requestAnimation=window.requestAnimationFrame,      start=dateNow(),      stop,      timeoutFunc=function(){       dateNow()-start<delay?stop||requestAnimation(timeoutFunc):callback()      };  requestAnimation(timeoutFunc);  return{   clear:function(){stop=1}  } } 

RafInterval

window.rInterval=function(callback,delay){  var dateNow=Date.now,      requestAnimation=window.requestAnimationFrame,      start=dateNow(),      stop,      intervalFunc=function(){       dateNow()-start<delay||(start+=delay,callback());       stop||requestAnimation(intervalFunc)      }  requestAnimation(intervalFunc);  return{   clear:function(){stop=1}  } } 

Usage

var interval1,timeout1; window.onload=function(){  interval1=window.rInterval(function(){console.log('interval1')},2000);  timeout1=window.rtimeOut(function(){console.log('timeout1')},5000); }  /* to clear interval1.clear(); timeout1.clear(); */ 

Demo

jsFiddle

Questions

  1. Normally I don't write functions inside functions, but in this case it's probably a good solution. What about memory leaks if I create hundreds of these time-based functions?

  2. Is there a better solution to clear those functions?

  3. For heavy animations and multiple intervals and timeouts, I was thinking to activate a single requestAnimationFrame() loop which would check for intervals and timeouts inside a previously stored array... (but I think there should be no difference if there is just one requestAnimationframe or multiple). So how do the browsers handle those multiple requestAnimationframes()?

Note:

If the code above does not work here is the original code:

window.rInterval=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b||(e+=b,a());f||d(g)};d(g);return{clear:function(){f=1}}}//callback,delay window.rtimeOut=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b?f||d(g):a()};d(g);return{clear:function(){f=1}}} 
           
       
       

Lista de respuestas

6
 
vote
vote
La mejor respuesta
 

Actualización 4/23/2014:

Bien, entonces, a su código actualizado. Nada puedo hacer aquí ahora. Aquí hay algunos consejos de optimización de código genérico:

  • Nombre 'Verbosely. Es un problema que encuentro con el código de otros. Tienden a nombrarlo como t por tiempo, o l1 por longitud. A menos que sea algo implícito, como i , j3 k4 Para los contadores (y vemos los bucles), nombrarlos verbosamente.

  • nunca te preocupes por el código largo. Para eso son los minificadores. Nombra verbosamente, estructure correctamente. Ni siquiera se moleste con el "COMMA Separado var S". Los minificadores hacen eso.

  • Ternarios tienden a ser desordenados e ilegibles. Si es posible, use if-else . Nuevamente, los minificadores también los convierten a ternarios para ser más cortos.

  • En cuanto a los posibles cuellos de botella, 9988776655544337 es una sobrecarga porque cambia el tamaño de la matriz, cambiando los contenidos alrededor. Se evita mucho como unshift y shift por la misma razón. No sé si mantener un "agujero" en la matriz, es un beneficio de rendimiento, así que lo dejemos como está.

  • Una punta de rendimiento general es solo para evitar crear objetos dentro de los bucles. Si no puede ser evitado, solo asegúrese de liberarlos cuando haya hecho (referencias gratuitas).

hasta ahora, eso es todo. Dejaré el ajuste fino para ti.

Respuesta previa:

Normalmente, no escribo funciones dentro de las funciones, pero en este caso es una buena solución. ¿Qué pasa con las fugas de la memoria si creo cientos de estas funciones cubidas de tiempo?

Eso no sería un problema. Además, ¿cuántas funciones crees que la página de inicio de FB, o algún sitio para el caso, crea? Sin embargo, de lo que debe tener cuidado, es cuando sus temporizadores crean funciones en cada iteración. Eso es lo que debes buscar. A lo largo de esto:

  l0  

Aunque algunos motores JS son lo suficientemente inteligentes como para resolver esto y sacar la función, he visto que el desempeño disminuye al hacer esto en algunos de mis proyectos.

¿Hay una mejor solución para borrar esas funciones?

Estaba pensando en algo a lo largo de la línea de una función común que puede ser referenciada por cada función API para generar un corredor. De esta manera, tenemos una función sentada internamente a la espera de ser llamada, en lugar de una creación de cada llamada.

  l1  

Para animaciones pesadas y múltiples intervalos, los tiempos de espera que estaba pensando en activar un solo bucle de solicitud de solicitud que verifique los intervalos y los tiempos de espera dentro de una matriz que se almacena anteriormente ...

La última vez que revisé, en bucle a través de una matriz con más de 700 artículos causados ​​por tartamudeo en la interfaz de usuario. Además, por la naturaleza de los temporizadores, en realidad se pueden retrasar las operaciones. Nuevamente, JS es un solo roscado, y los temporizadores también viven en ese hilo. Si JS está ocupado batiendo, puede retrasar las tareas de ASYNC y que incluye temporizadores.

l2 de un vistazo

Una cosa sobre l3 es que está construido para la animación. Se esfuerza por darle una 60 fps. Sin embargo, cuando no puede, no es diferente de l4 y l5 . Además, depende de la implementación del navegador. Algunos navegadores temporizadores de aceleración según diferentes situaciones, como Windows / Tabs desenfocados.

Vamos a iniciar la selección de cerezos

Aquí están aquí algunas cosas interesantes sobre su implementación:

  • Tiene una función interna en cada instancia de un temporizador. Parece la raíz de tus preocupaciones.
  • Pero también devuelve un objeto para cada instancia para el l6 . ¿Por qué no almacenar algún tipo de referencia a los temporizadores de ejecución y crear otra función global que los elimina?
  • Como lo descubrió, 60FPS tiene 16 ms por sorteo. Sin embargo, Los temporizadores son tan rápidos como 4ms .
 

Update 4/23/2014:

Okay then, off to your updated code. Nothing much I can do here now. Here are some generic code optimization tips:

  • Name stuff verbosely. It's one issue I find with others' code. They tend to name it like t for time, or l for length. Unless it's something implied, like i,j and k for counters (and we do see loops), please name them verbosely.

  • Don't ever worry about long code. That's what minifiers are for. Name them verbosely, structure them properly. Don't even bother using the "comma-separated vars". Minifiers do that.

  • Ternaries tend to be messy and unreadable. If possible, use if-else. Again, minifiers also convert them to ternaries to be shorter.

  • As for possible bottlenecks, splice is an overhead because it resizes the array, shifting the contents around. It's much avoided like unshift and shift for the same reason. I don't know if keeping a "hole" in the array is a performance benefit either, so let's leave it as is.

  • A general performance tip is just to avoid creating objects inside the loops. If it can't be avoided, just make sure you free them up when done (free references).

So far, that's about it. I'll leave the fine-tuning to you.

Previous answer:

Normally i don't write functions inside functions, but in this case it's prolly a good solution. What about memory leaks if i create hundreds of this timebased functions?

That wouldn't be an issue. Besides, how many functions do you think the FB homepage, or any site for that matter, creates? What you should be wary about, though, is when your timers create functions on every iteration. That's what you should look out for. Along the lines of this:

function tick(){   requestAnimationFrame(tick);    // Oh...   var aFunctionMadeOnEachTick = function(){...};   aFunctionMadeOnEachTick(); } 

Although some JS engines are smart enough to figure this out and pull out the function, I have seen performance decreases when doing this in some of my projects.

Is there a better solution to clear those functions?

I was thinking about something along the lines of a common function that can be referenced by each API function to generate a runner. This way, we have one function sitting internally waiting to be called, instead of one created each call.

;(function (ns) {      // An array of references/ids/booleans/whatever that can be used to clear off running timers   var timers = [];    // The common function   // Haven't figured out how the cb and delay gets called on the next tick, but   // this should be a good template to think about.   function runningFn(cb,delay) {     if(iShouldStillRun) requestAnimationFrame(runningFn);     if(Date.now() > something) execute();   }    // Your API functions   ns.setTimeOut    = function (callback, delay) {     runningFn(callback,delay);   }   ns.setInterval   = function (callback, delay) {...}   ns.clearInterval = function (callback, delay) {...}   ns.clearTimeout  = function (callback, delay) {...}  }(this.Timers = this.Timers || {})); 

For heavy animations and multiple intervals,timeouts i was thinking to activate a single requestAnimationFrame loop which check for intervals and timeouts inside a previously stored array...

The last time I checked, looping through an array with 700+ items caused stuttering in the UI. Also, by the nature of timers, they can actually be delayed by these operations. Again, JS is single-threaded, and timers also live in that thread. If JS is busy churning, it can delay async tasks and that includes timers.

rAF at a glance

One thing about rAF is that it's built for animation. It strives to give you a 60fps. However, when it can't, it isn't any different from setInterval and setTimeout. Also, it depends on browser implementation. Some browsers throttle timers according to different situations, like unfocused windows/tabs.

Let's start cherry-picking

Now here are some interesting things about your implementation:

  • You have an internal function in each instance of a timer. Looks like the root of your worries.
  • But you also return an object for each instance for the clear. Why not store some sort of reference to running timers, and create another global function that clears them?
  • Like you found out, 60fps is 16ms per draw. However, timers are as fast as 4ms.
 
 
         
         

Relacionados problema

7  Una secuencia parcialmente superpuesta de animaciones jQuery  ( A partially overlapping sequence of jquery animations ) 
¡Sé que este es un desastre! ¿Cómo puedo escribir este código mejor? function anim() { $( "#p1-animation-1" ).fadeIn( 1200, function() { ...

2  Animar una caja, rebotando a la izquierda y la derecha  ( Animate a box bouncing left and right ) 
Escribí el siguiente código para mover un cuadro a la derecha y devolverlo a la izquierda, y repetir esta acción para siempre. Este código funciona, pero ¿h...

1  Manipulador de eventos repetitivos para un control de interfaz de usuario de la UI  ( Repetitive event handler for a toggling ui control ) 
Siento que este tipo de código podría haber sido escrito más elegante, especialmente con las enormes afirmaciones de IF / ODS. ¿Alguien puede ayudarme a rompe...

1  Animación "Star Field" con JavaScript y Sass-CSS  ( Star field animation with javascript and sass css ) 
He hecho esta animación el fin de semana como una cosa "solo por diversión". Y para jugar con varias técnicas que he visto en otros Código. Creo que funcion...

3  Forma aceptable de usar métodos jQuery en directivas angulares  ( Acceptable way of using jquery methods in angular directives ) 
aquí es mi ejemplo de plunker de lo que estoy haciendo. jQuery es una excelente manera de usar transiciones de diapositivas y parece funcionar bien con an...

2  Los efectos de desplazamiento, fade-in y fade-out se sienten clunky  ( Scrolling fade in and fade out effects feeling clunky ) 
Estoy cerca de terminar un sitio donde hay una serie de funciones de jQuery que están pasando. Todos trabajan, pero la página está corriendo un poco demasiado...

4  Carrusel para sitio web  ( Carousel for website ) 
He estado construyendo mi propio carrusel en los últimos días. No soy un guru jquery, solo un entusiasta, y creo que mi código es un poco descuidado, de ahí l...

2  Animaciones de la línea de tiempo  ( Timeline animations ) 
Hice recientemente esta línea de tiempo del campus para mi universidad. Al ver la línea de tiempo en un dispositivo móvil (no una tableta), la barra de nave...

12  Impresión similar a la consola del mensaje JavaScript  ( Console like printing of message javascript ) 
Estoy aprendiendo a Javascript y he hecho un pequeño script de modificación de documentos muy simple que imprime un mensaje como si fuera alguien escribiendo ...

3  Cajas de texto ampliables para leyendas de campos  ( Expandable text boxes for legends of fieldsets ) 
¿Cuál es la mejor manera de refactorizar el siguiente script? <?php // First we execute our common code to connection to the database and start the s...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos