J'ai mis en place quelques tests simples qui rendent une image sur une toile. L'un rend à partir d'un IMG, tandis que l'autre rend à partir d'un CANVAS hors écran. Vous pouvez voir le code et les résultats ici: http://jsperf.com/canvas-rendering/2
Dans la plupart des navigateurs, le rendu à partir d'une image est beaucoup plus rapide que le rendu à partir d'un canevas, sauf dans Chrome, où la situation est inversée. Quelqu'un peut-il expliquer la raison des différences? Après tout, nous rendons les mêmes données de pixels à la même destination.
html-canvas
alekop
la source
la source
Réponses:
OK, je l'ai compris. Presque. C'est en fait assez évident, et je me sens un peu stupide de ne pas l'avoir remarqué tout de suite. Lorsque vous appelez
drawImage(src, 0, 0)
sans spécifier de largeur / hauteur, il dessine toute la région src, qui dans ce cas est beaucoup plus grande (le canevas est de 320x420 contre l'img à 185x70). Ainsi, dans le cas du canevas, le navigateur fait beaucoup plus de travail, ce qui explique le ralentissement des performances. Je suis toujours perplexe devant le score plus élevé de Chrome avec le plus grand src.J'ai publié une version mise à jour qui utilise les mêmes régions, et les différences sont beaucoup plus proches. http://jsperf.com/canvas-rendering/5
Je ne peux toujours pas expliquer pourquoi il y a une différence, mais elle est maintenant suffisamment petite pour que je m'en fiche vraiment.
la source
Chrome est susceptible d'utiliser l'accélération matérielle.
Créez un canevas 240x240 et exécutez votre test dans Chrome, puis créez un canevas 300x300 et recommencez. La toile plus grande que je m'attends à être plus rapide en raison du fait que l'accélération matérielle se déclenche après 256x256 et que Chrome utilise un logiciel lorsque les tailles sont inférieures.
Il convient également de souligner que -webkit-transform: translateZ (0) désactive l'accélération matérielle.
Je n'ai testé aucun des éléments ci-dessus; Je le sais uniquement en raison du fait qu'un des ingénieurs de Chrome a commenté un bogue que j'ai signalé dans Chrome lorsque vous franchissez le seuil matériel et logiciel en redimensionnant dynamiquement le canevas de plus grand à plus petit que la limite 256x256 ou vice-versa. La solution à ce bogue était de désactiver l'accélération en utilisant translateZ comme mentionné ci-dessus.
Dans mon cas, je n'ai tout simplement pas autorisé les utilisateurs à redimensionner moins de 256x256.
la source
Parfois, les images peuvent être chargées dans la mémoire du GPU et dans la mémoire de l'hôte. Dans ce cas, lorsque vous dessinez de l'image vers le canevas, les données d'image doivent être copiées d'abord dans la mémoire hôte, puis dans le canevas.
J'ai remarqué ce genre de comportement avec Chrome, lorsque j'écrivais un projet qui charge plus de 100 millions d'images pixel, puis en lit des parties sur un petit canevas 256 x 256 ( http://elhigu.github.io/canvas-image-tiles/ ).
Dans ce projet, si je dessinais directement de la balise d'image vers le canevas dans Chrome, la mémoire sautait toujours à ~ 1,5 Go au début du dessin, puis à la fin du dessin, la mémoire était à nouveau libérée, même cette image source de 250 mégapixels était affichée tout le temps dans la page.
J'ai résolu le problème en écrivant une fois l'image sur une grande toile (même taille avec l'image), puis en dessinant une petite toile à partir de là (j'ai également jeté l'image après l'avoir convertie en toile).
la source
Je ne peux pas expliquer les différences, mais je ne suis pas d'accord avec
Si vous regardez les résultats sur le js.pref, les différences de chrome sont assez subtiles. Je préfère le rendu à partir d'une image lorsque cela est possible.
la source
La taille de l'image est de 185 * 70 mais nous créons un canevas avec la taille, je pense que cela gâchera certaines performances, donc j'ai réglé la taille du canevas hors écran de la même manière que l'image. Et la différence est plus proche.
http://jsperf.com/canvas-rendering/60
la source