Reuní un par de pruebas simples que representan una imagen en un lienzo. Uno representa desde un IMG, mientras que el otro representa desde un CANVAS fuera de pantalla. Puede ver el código y los resultados aquí: http://jsperf.com/canvas-rendering/2
En la mayoría de los navegadores, la representación desde una imagen es mucho más rápida que la representación desde un lienzo, excepto en Chrome, donde la situación se invierte. ¿Alguien puede explicar la razón de las diferencias? Después de todo, estamos representando los mismos datos de píxeles en el mismo destino.
html-canvas
alekop
fuente
fuente
Respuestas:
OK, lo descubrí. Casi. En realidad es bastante obvio, y me siento un poco tonto por no notar esto de inmediato. Cuando llama
drawImage(src, 0, 0)
sin especificar el ancho / alto, dibuja toda la región src, que en este caso es mucho más grande (el lienzo es 320x420 frente al img a 185x70). Entonces, en el caso del lienzo, el navegador está haciendo mucho más trabajo, lo que explica el rendimiento más lento. Todavía estoy desconcertado por la puntuación más alta de Chrome con el src más grande.He publicado una versión actualizada que usa las mismas regiones, y las diferencias están mucho más cercanas. http://jsperf.com/canvas-rendering/5
Todavía no puedo explicar por qué hay una diferencia, pero ahora es lo suficientemente pequeña como para que realmente no me importe.
fuente
Es probable que Chrome use aceleración de hardware.
Cree un lienzo 240x240 y ejecute su experimento en Chrome, luego cree un lienzo 300x300 y vuelva a hacerlo. El lienzo más grande que espero sea más rápido debido al hecho de que la aceleración de hardware se activa después de 256x256 y Chrome usa software cuando los tamaños son menores.
También vale la pena señalar que -webkit-transform: translateZ (0) desactiva la aceleración de hardware.
No he probado ninguno de los anteriores; Solo sé esto debido al hecho de que uno de los ingenieros de Chrome comentó un error que informé en Chrome cuando cruzas el umbral de hardware y software cambiando el tamaño dinámicamente del lienzo de mayor a menor que el límite de 256x256 o viceversa. La solución a este error fue desactivar la aceleración utilizando el translateZ como se mencionó anteriormente.
En mi caso, simplemente no permití que los usuarios redimensionaran menos de 256x256.
fuente
A veces, las imágenes pueden cargarse en la memoria de la GPU y el lienzo en la memoria del host. En ese caso, cuando dibuja desde la imagen al lienzo, los datos de la imagen deben copiarse primero en la memoria del host y luego en el lienzo.
Noté ese tipo de comportamiento con Chrome, cuando estaba escribiendo un proyecto que carga más de 100 millones de imágenes de píxeles y luego lee partes de ellas en un pequeño lienzo de 256x256 ( http://elhigu.github.io/canvas-image-tiles/ ).
En ese proyecto, si dibujaba directamente de la etiqueta de la imagen al lienzo en Chrome, la memoria siempre saltaba a ~ 1.5GB cuando comenzaba el dibujo y luego, cuando terminaba el dibujo, la memoria se liberaba nuevamente, incluso esa imagen de origen de 250 megapíxeles se mostraba todo el tiempo en la página.
Solucioné el problema escribiendo la imagen una vez en un lienzo grande (del mismo tamaño que la imagen) y luego dibujando un lienzo más pequeño desde allí (también tiré la imagen después de convertirla en lienzo).
fuente
No puedo explicar las diferencias, pero no estoy de acuerdo con
Si observa los resultados en js.pref, las diferencias en Chrome son bastante sutiles. Me quedaría con solo renderizar desde una imagen cuando sea posible.
fuente
El tamaño de la imagen es 185 * 70, pero creamos un lienzo con tamaño, creo que esto desperdiciará algo de rendimiento, por lo que configuré el tamaño del lienzo fuera de la pantalla igual que la imagen. Y la diferencia está más cerca.
http://jsperf.com/canvas-rendering/60
fuente