Ich habe ein paar einfache Tests zusammengestellt, die ein Bild auf eine Leinwand rendern. Einer rendert von einem IMG, während der andere von einem Offscreen-CANVAS rendert. Sie können den Code und die Ergebnisse hier sehen: http://jsperf.com/canvas-rendering/2
In den meisten Browsern ist das Rendern von einem Bild viel schneller als das Rendern von einer Leinwand, außer in Chrome, wo die Situation umgekehrt ist. Kann jemand den Grund für die Unterschiede erklären? Schließlich rendern wir dieselben Pixeldaten an dasselbe Ziel.
html-canvas
Alekop
quelle
quelle
Antworten:
OK, ich habe es herausgefunden. Fast. Es ist eigentlich ganz offensichtlich, und ich fühle mich ein bisschen dumm, weil ich das nicht sofort bemerkt habe. Wenn Sie
drawImage(src, 0, 0)
ohne Angabe von Breite / Höhe aufrufen , wird der gesamte src-Bereich gezeichnet, der in diesem Fall viel größer ist (die Zeichenfläche ist 320 x 420 gegenüber dem Bild bei 185 x 70). Im Canvas-Fall erledigt der Browser also viel mehr Arbeit, was die langsamere Leistung erklärt. Ich bin immer noch verwirrt über die höhere Punktzahl von Chrome mit dem größeren src.Ich habe eine aktualisierte Version veröffentlicht, die dieselben Regionen verwendet, und die Unterschiede sind viel enger. http://jsperf.com/canvas-rendering/5
Ich kann immer noch nicht erklären, warum es einen Unterschied gibt, aber es ist jetzt klein genug, dass es mich nicht wirklich interessiert.
quelle
Chrome verwendet wahrscheinlich die Hardwarebeschleunigung.
Erstellen Sie eine Leinwand 240 x 240 und führen Sie Ihr Experiment in Chrome aus. Erstellen Sie dann eine Leinwand 300 x 300 und wiederholen Sie den Vorgang. Die größere Leinwand, von der ich erwarte, dass sie schneller ist, da die Hardwarebeschleunigung nach 256 x 256 einsetzt und Chrome Software verwendet, wenn die Größen kleiner sind.
Es ist auch erwähnenswert, dass -webkit-transform: translateZ (0) die Hardwarebeschleunigung deaktiviert.
Ich habe keines der oben genannten getestet. Ich weiß das nur, weil einer der Chrome-Ingenieure einen Fehler kommentiert hat, den ich in Chrome gemeldet habe, als Sie den Hardware- und Software-Schwellenwert überschritten haben, indem Sie die Größe der Zeichenfläche dynamisch von größer auf kleiner als die 256x256-Grenze geändert haben oder umgekehrt. Die Lösung für diesen Fehler bestand darin, die Beschleunigung mit dem oben erwähnten translateZ auszuschalten.
In meinem Fall habe ich Benutzern einfach nicht erlaubt, die Größe von weniger als 256 x 256 zu ändern.
quelle
Manchmal werden Bilder in den GPU-Speicher und die Zeichenfläche im Host-Speicher geladen. In diesem Fall müssen beim Zeichnen von Bild zu Zeichenfläche die Bilddaten zuerst in den Hostspeicher und dann in die Zeichenfläche kopiert werden.
Ich habe diese Art von Verhalten bei Chrome bemerkt, als ich ein Projekt schrieb, das über 100 Millionen Pixelbilder lädt und dann Teile davon auf eine kleine Leinwand mit 256 x 256 ( http://elhigu.github.io/canvas-image-tiles/ ) liest .
Wenn ich in diesem Projekt in Chrome direkt vom Bild-Tag auf die Leinwand zeichnete, sprang der Speicher beim Starten des Zeichnens immer auf ~ 1,5 GB, und wenn das Zeichnen beendet wurde, wurde der Speicher wieder freigegeben, selbst das 250-Megapixel-Quellbild wurde die ganze Zeit auf der Seite angezeigt.
Ich habe das Problem behoben, indem ich das Bild einmal auf eine große Leinwand geschrieben habe (gleiche Größe wie das Bild) und dann eine kleinere Leinwand von dort gezeichnet habe (ich habe das Bild auch weggeworfen, nachdem ich es in Leinwand konvertiert hatte).
quelle
Ich kann die Unterschiede nicht erklären, aber ich würde dem nicht zustimmen
Wenn Sie sich die Ergebnisse auf dem js.pref ansehen, sind die Unterschiede in Chrom ziemlich subtil. Wenn möglich, bleibe ich beim Rendern von einem Bild.
quelle
Das Bild hat eine Größe von 185 * 70, aber wir erstellen eine Leinwand mit einer Größe. Ich denke, dies wird etwas Leistung verschwenden. Deshalb habe ich die Größe der Leinwand außerhalb des Bildschirms auf das gleiche Bild eingestellt. Und der Unterschied ist näher.
http://jsperf.com/canvas-rendering/60
quelle