Подтвердить что ты не робот

Проблемы с производительностью с холстом HTML5 в некоторых мобильных браузерах.

Привет, у меня есть Webapp, который должен работать как на смартфонах, так и на обозревателях рабочего стола. В то время как я ожидал получить любопытное поведение на небольших устройствах, таких как Iphone, я был довольно уверен, что он будет хорошо работать на Android Galaxy Tab, который является Android-устройством, на котором я могу запускать тесты на данный момент.

Теперь я установил кучу браузеров на вкладке Galaxy для проверки:

  • Основной браузер Android
  • Chrome для Android
  • Firefox для Android

На рабочем столе я использовал

  • Firefox
  • Google Chrome

и, наконец, у меня есть Iphone для тестирования.

Веб-сайт использует холст HTML5 для рисования на основе пикселов и спрайтов без фантастических преобразований, фильтров или эффектов, в основном простых путей и полигонов. Я слушаю события касания и использую requestAnimationFrame для правильной перерисовки.

В целом приложение хорошо работает на настольных браузерах, оно отлично работает и на iOS Safari (iPhone) и Firefox-on-Android. Тем не менее Андроиды Native Browser дают мне проблемы. Я настроил его так, чтобы экран краснел, когда javascript не реагирует, и он почти мгновенно мигает при касании экрана.

Итак, я задаюсь вопросом, есть ли какие-либо известные проблемы с Android Native App и HTML5. Из-за несуществующего имени собственного браузера довольно сложно сообщить об этом Google. Любые идеи для меня, где я могу получить дополнительную информацию? Любые идеи, которые могут вызвать отставание в родном Android-браузере?

Есть несколько идей о проблеме:

  • iOS не поддерживает requestAnimationFrame, поэтому я заменил его заменой на время ожидания. Если я использую эту замену на родном браузере Android, проблема не исчезнет.

  • Я использую AJAX (google clojure xhrio) достаточно регулярно, чтобы извлекать данные с сервера. Может ли быть, что обратные вызовы восстановления данных засоряют мой конвейер событий?

  • Известны ли сообщения консоли консоли (console.log) для замедления приложений? Могут ли они вызвать браузер для повторного запуска через дерево DOM или что-то связанное?

4b9b3361

Ответ 1

Я провел много экспериментов с холстом во многих браузерах. Некоторые проблемы с производительностью, которые я заметил:

Во-первых, о ваших предположениях:

  • Когда requestAnimationFrame поддерживается браузером, материал чертежа и само приложение более отзывчивы. Используйте setTimeout или setInterval, так как резерв всегда возможен, но вам нужно быть осторожным в отношении времени. Этот надежный polyfill может помочь немного, но ничего не по сравнению с native requestAnimationFrame.

  • Если console.log вызывается каждый кадр (или почти), да, производительность снижается. Поскольку собственный Android-браузер не имеет консольного объекта, каждый раз, когда он вызывается, генерируется ошибка, которая также способствует замедлению вашего приложения. Вы можете сделать это:

    if(typeof console === "undefined"){ console = {}; }

  • Для интенсивных приложений реального времени веб-сокеты быстрее, чем HTTP-запросы. К сожалению, эта функция не поддерживается старыми встроенными браузерами. Если невозможно использовать веб-сокеты, вы должны свести к минимуму http-запросы.

Примечание. Chrome для поддержки Android большинство функций HTML5, перечисленных здесь, включая requestAnimationFrame и websockets.

Дополнительная информация:

  • Рисование текста с использованием контекста 2d fillText слишком дорого, но в некоторых браузерах это еще хуже. Предварительно создайте свои тексты на другом холсте или используйте растровые шрифты. (В родном Android-браузере, после замены рисунка fillText для предварительного рендеринга, производительность выросла с 10-15 FPS до 30-45 FPS в некоторых играх, которые я сделал).

  • Избегайте масштабирования и поворота контекста, потому что они также вызывают снижение производительности. Если вам нужно масштабировать или поворачивать спрайт только один раз, используйте предварительную визуализацию.

  • Вам нужно минимизировать рисование в реальном времени. Предоставляйте свои вещи, когда сможете. Переделайте только те материалы, которые изменились и их необходимо обновить.

  • Попробуйте написать эффективную память и код для коллекционера мусора.

Есть намного больше дел. Я просто привел несколько.

СОВЕТ: сделайте несколько стресс-тестов для функций, которые вы не уверены, являются ли они убийцами производительности и фиксируют результаты тестов.

В мобильных приложениях, особенно в приложениях реального времени, все оптимизаторы приветствуются без матер, если это просто оптимизация или бит памяти.

Для получения дополнительной информации перейдите по ссылкам ниже:

Также найдите производительность в Сообщениях и учебниках.

ИЗМЕНИТЬ
Этот фрагмент кода jsfiddle показывает некоторые вещи, которые рассматриваются в этом ответе, и предоставляет приблизительный счетчик кадров в секунду для сравнения. Отредактируйте эту скрипку самостоятельно и проверьте ее.

Ответ 2

В зависимости от того, что вы рисуете, наиболее распространенной стратегией улучшения производительности с холстом Html5 является использование слоев (т.е. нескольких холстов) и обновление только слоев, которые нужно перерисовать, а не перерисовывать всю вещь на каждом кадре анимации. Вы можете перевернуть что-то подобное себе, или вы можете использовать что-то вроде http://www.concretejs.com/, которое представляет собой легкую структуру холста Html5, которая позволяет использовать такие периферийные объекты, как обнаружение попадания, слоирование, кеширование, поддержка соотношения пикселей, загрузки и т.д. Вы бы сделали примерно следующее:

var wrapper = new Concrete.Wrapper({
  width: 500,
  height: 300,
  container: el
});

var layer1 = new Concrete.Layer();
var layer2 = new Concrete.Layer();

wrapper.add(layer1).add(layer2);

// something happens which requires you to redraw layer2, but not layer1...
layer2.sceneCanvas.context.fillStyle = 'red';
layer2.sceneCanvas.context.fillRect(0, 0, 200, 100);