2012-03-22 8 views
6

Tengo una página que tiene operaciones bastante pesadas (en lugar de peso medio) canvas pasando. Para atender a los usuarios en dispositivos móviles y computadoras antiguas, pensé que podría implementar un mecanismo que verificará si el elemento de lienzo es realmente visible y decidirá si los cálculos constantes y las actualizaciones de lienzo (animación a 30 fps) deben realizarse o no. .¿Los navegadores representan elementos de lienzo que no están dentro de la ventana gráfica?

Esto está trabajando muy bien, sin embargo, cuando se hace una prueba de funcionamiento con las herramientas de Chrome Dev me di cuenta de que incluso cuando desactivo mi cheque visibilidad y dejar que las cosas hacen que todo el tiempo del uso de la CPU de la función en cuestión cae un poco cuando ninguna parte del elemento (s) del lienzo es visible (aunque en teoría aún debería realizar las mismas tareas). Entonces: al menos en mi computadora con Chrome 17, no hay una diferencia real si verifico la visibilidad real del elemento.

Para resumir: ¿Tengo que hacer esto o soy navegadores lo suficientemente inteligentes como para manejar un caso así sin siquiera decirles (y puedo guardar la verificación de visibilidad)?


EDITAR:

así que hice un poco de "investigación" sobre este tema y construido this fiddle.

Lo que pasa es que simplemente genera ruido a 30 fotogramas por segundo. No es muy agradable a la vista, pero ... bueno, la parte superior es simplemente div para bloquear la ventana gráfica. Cuando me desplazo hacia abajo y tengo el elemento canvas en la ventana gráfica, el uso de la CPU me dice que está ocupando aproximadamente el 40%, por lo que aparentemente el navegador tiene bastante que hacer aquí. Cuando me desplazo hacia arriba para tener el color granate div en mi ventana gráfica y el perfil del uso de la CPU, se reduce a un 10%. Cuando me desplazo hacia abajo, el uso vuelve a aumentar.

Así que cuando implemente un control de la visibilidad como en este modified fiddle, veo un aumento (uno pequeño para ser honesto) en el uso de la CPU en lugar de una gota (ya que tiene la tarea adicional de comprobar si el lienzo está dentro de la ventana gráfica).

Así que todavía me pregunto si esto es un efecto secundario de algo de lo que no estoy enterado (o estoy cometiendo un gran error al crear perfiles) o si puedo esperar que los navegadores sean lo suficientemente inteligentes como para manejar tales situaciones?

¡Si alguien pudiera arrojar algo de luz sobre eso estaría muy agradecido!

Respuesta

8

creo que usted está confundido entre si la lógica está funcionando y si la representación está sucediendo. Muchos navegadores ahora aceleran sus lienzos de hardware para que todas las renderizaciones ocurran en la GPU, de modo que el empuje real de píxeles no requiere tiempo de CPU. Sin embargo, su función tick tiene un código no trivial para generar ruido aleatorio en la CPU. Entonces, solo está realmente preocupado sobre si la función tick se está ejecutando.Si el lienzo está fuera de la pantalla, ciertamente no se mostrará en la pantalla (no está visible). En cuanto a las llamadas al sorteo, probablemente dependa del navegador. Podría procesar todas las llamadas a un lienzo fuera de pantalla en caso de que de repente lo muevas hacia atrás para verlo, o simplemente podría poner en cola todas las llamadas al sorteo y no hacer nada con ellas hasta que no desplace el lienzo para verlas. No estoy seguro de qué hace cada navegador allí.

Sin embargo, no debe usar setInterval o setTimeout para animar Canvas. Use la nueva API requestAnimationFrame. Los navegadores no saben qué hacer en una llamada con temporizador, por lo que siempre llamará al temporizador. requestAnimationFrame por otro lado está diseñado específicamente para cosas visuales, por lo que el navegador tiene la oportunidad de no llamar a la función de marcar, o para reducir la tasa a la que se llama, si el lienzo o la página no está visible.

En cuanto a cómo los navegadores realmente lo manejo, no estoy seguro. Sin embargo, definitivamente debería preferirlo, ya que los futuros navegadores pueden optimizar mejor requestAnimationFrame en formas que no pueden optimizar setInterval o setTimeout. Creo que los navegadores modernos también reducen los temporizadores ordinarios a 1 Hz si la página no está visible, pero definitivamente es mucho más fácil para el navegador optimizar requestAnimationFrame, además de que algunos navegadores le permiten sincronizar en V y otros aspectos agradables.

No estoy seguro de que requestAnimationFrame signifique que su función de marcar no se invoque si el lienzo se desplaza fuera de la vista. Así que recomendaría usar tantorequestAnimationFrame como la verificación de visibilidad existente. Eso debería garantizarle la representación más eficiente.

+0

Guau, ¡muchas gracias por esa respuesta tan completa! He escuchado sobre 'requestAnimationFrame' antes, pero lo que siempre me molestó es que parece apuntar a que la animación se ejecute a 60 fps sin importar qué (lo que sí creo que se ve demasiado suave para muchos tipos de animación). La única forma de limitar esto que podía pensar una vez más incluía un 'setInterval' ... ¿Sabes si hay alguna forma de restringir/alterar eso? – m90

+0

¿Demasiado suave? Nunca he oído hablar de una animación demasiado suave, ¿qué pasa con eso? : S – AshleysBrain

+0

Puede sonar raro, pero tengo experiencia en animación clásica, así que realmente creo a 12 fps, pensando que esto ya es parte de mi cerebro. Mi objeción puede ser tonta en el 95% de los casos, pero en ciertos casos sería increíble tener más control. – m90

2

Según mi propia experiencia, representa todo lo que le digas para representar independientemente de la posición en la pantalla.

Un ejemplo es si dibuja mosaicos, que excede el tamaño del lienzo, aún verá la caída del rendimiento a menos que optimice el guión.

Pruebe su función con una animación exigente de rendimiento, y vea si todavía obtiene los mismos resultados.

+0

La caída en el uso de la CPU parece ocurrir cuando todo el elemento '' se desplaza fuera de la pantalla. Tal como lo escribió, no parece marcar una diferencia si solo ve una altura de 2px o todo. – m90

+0

Esa podría ser la misma razón que cuando sales del sitio web. El navegador sabe que el lienzo no está a la vista y, por lo tanto, entra en modo inactivo. Intenta tabular y volver 5 minutos más tarde y la animación será más o menos donde la dejaste. – justanotherhobbyist

Cuestiones relacionadas