Я собрал пару простых тестов, которые отображают изображение на холсте. Один визуализируется из IMG, а другой - из закадрового CANVAS. Вы можете увидеть код и результаты здесь: http://jsperf.com/canvas-rendering/2
В большинстве браузеров рендеринг с изображения выполняется намного быстрее, чем с холста, за исключением Chrome, где ситуация обратная. Кто-нибудь может объяснить причину различий? В конце концов, мы рендерим одни и те же данные пикселей в одном и том же месте назначения.
html-canvas
alekop
источник
источник
Ответы:
Хорошо, я понял это. Почти. Это на самом деле довольно очевидно, и я чувствую себя немного глупо, что не заметил этого сразу. При вызове
drawImage(src, 0, 0)
без указания ширины / высоты он рисует всю область src, которая в этом случае намного больше (холст 320x420 по сравнению с img 185x70). Так что в случае холста браузер делает гораздо больше работы, что объясняет более низкую производительность. Я все еще озадачен более высоким счетом Chrome с большим SRC.Я опубликовал обновленную версию, которая использует те же регионы, и различия гораздо ближе. http://jsperf.com/canvas-rendering/5
Я до сих пор не могу объяснить, почему есть разница, но сейчас она настолько мала, что мне все равно.
источник
Chrome, скорее всего, будет использовать аппаратное ускорение.
Создайте холст 240x240 и запустите эксперимент в Chrome, затем создайте холст 300x300 и повторите его. Я ожидаю, что больший холст будет быстрее из-за того, что аппаратное ускорение включится после 256x256, а Chrome использует программное обеспечение, когда размеры меньше.
Также стоит отметить, что -webkit-transform: translateZ (0) отключает аппаратное ускорение.
Я не проверял ничего из вышеперечисленного; Я знаю это только из-за того, что один из инженеров Chrome прокомментировал ошибку, о которой я сообщил в chrome, когда вы пересекаете аппаратный и программный порог, динамически изменяя размер холста от большего к меньшему, чем граница 256x256 или наоборот. Решением этой ошибки было отключение ускорения с помощью translateZ, как упомянуто выше.
В моем случае я просто не позволял пользователям изменять размер менее 256x256.
источник
Иногда изображения могут быть загружены в память графического процессора и холст в памяти хоста. В этом случае, когда вы рисуете с изображения на холст, данные изображения должны быть сначала скопированы в память хоста, а затем в холст.
Я заметил такое поведение с Chrome, когда писал проект, который загружает изображения размером более 100 миллионов пикселей, а затем читает их части на небольшом холсте размером 256x256 ( http://elhigu.github.io/canvas-image-tiles/ ).
В этом проекте, если я рисовал непосредственно из тега изображения на холст в Chrome, память всегда переходила к ~ 1,5 ГБ, когда началось рисование, а затем, когда рисование заканчивалось, память снова освобождалась, даже исходное изображение размером 250 мегапикселей все время отображалось на странице.
Я исправил проблему, записав изображение один раз на большой холст (того же размера, что и изображение), а затем нарисовав оттуда меньший холст (я также выбросил изображение после преобразования его в холст).
источник
Не могу объяснить различия, но я не согласен с
Если вы посмотрите на результаты в js.pref, различия в chrome довольно тонкие. Я бы придерживался только рендеринга с изображения, когда это возможно.
источник
Размер изображения 185 * 70, но мы создаем холст с размером, я думаю, что это приведет к потере производительности, поэтому я установил размер внеэкранного холста так же, как изображение. И разница ближе.
http://jsperf.com/canvas-rendering/60
источник