Почему FPS понижается, если canvas больше 255x220?
Я нашел странное явление с HTML5 canvas. Я получал более низкую, чем ожидалось, частоту кадров, но только в Firefox и только на одном компьютере (но не на другом, который я тестировал). Самое странное, что если я уменьшу размер холста до 255x250 или меньше, Firefox будет работать аналогично другим браузерам. Если я добавлю еще один пиксель в ширину, FPS быстро падает до третьего.
Я сделал jsPerf, чтобы продемонстрировать проблему: http://jsperf.com/critical-canvas-size(Убедитесь, что на экране отображается серый прямоугольник. Если нет, я допускаю, чтобы тесты не выполнялись, потому что я обнаружил, что это меняет результаты если вы прокрутите случайно.)
Все четыре тестовых примера очень похожи на большинство браузеров на большинстве систем, но на этом одном ПК с Firefox 17 я вижу следующее:
Рассматриваемый ПК работает под управлением более старой Red Hat Linux, и, вероятно, на нем нет поддержки аппаратного ускорения (со стороны ОС).
Итак, что может быть причиной этого? Что я могу сделать в своем коде, чтобы обойти проблему? (Например, я думал об использовании нескольких небольших полотен вместо одного большого).
Изменить: Вот автономный HTML-файл, который решает проблему, и тот, который не. Единственная разница - ширина холста, 251 против 250. (Вы можете закомментировать анимацию вращения, это просто, чтобы сделать проблему видимой. Также, пожалуйста, извините за точность таймера FPS, его реализация очень проста.)
Версия 250px получает около 60 FPS, на самом деле, похоже, она ограничена. Вы можете увеличить numIterations
переменная, чтобы функция фрейма рисовала множество плиток. Я могу получить до numIterations = 100 или 120000 плиток / сек, но при этом иметь приличную частоту кадров. Тем не менее, версия 251px дает мне даже для numIterations = 1 частоту кадров ниже 20 или менее 1000 плиток / сек.
2 ответа
Это имеет смысл, потому что рисование на холсте и очистка холста - дорогие методы; если у вас есть холст поменьше и звоните clearRect
на каждом шаге анимации он будет работать лучше, чем холст большего размера, выполняющий точно такой же код. Лучше всего оптимизировать метод рисования, чтобы очистить только то, что изменило каждый кадр. Как только вы это сделаете, вы заметите повышение производительности; эта статья поможет в других областях, в которых вы можете повысить производительность.
Я тоже занимаюсь разработкой с использованием canvas и обнаружил, что браузеры на основе WebKit, как правило, выполняют операции с холстом быстрее, чем Gecko в большинстве случаев.
Я на самом деле вижу подобное поведение. Я считаю, что это когда вы преодолеваете барьер 65776 пикселей -> не 65536, как вы ожидаете.
Я пока не знаю, почему это так, но, скорее всего, это какая-то внутренняя структура данных или проблема с типом данных (возможно, из-за использования хеша и для этого необходимо увеличить таблицу) внутри вашего браузера. Ваш тест на самом деле недействителен в моем браузере Chrome - он не показывает того же падения производительности.
Я написал несколько тестовых примеров http://jsperf.com/pixel-count-matters/2 и http://jsperf.com/magic-canvas/2
Надеюсь это поможет!