Коварные анимации на Windows Phone

в 13:58, , рубрики: .net, storyboard, windows phone, XAML, анимации, разработка под windows phone, метки: , , ,

Когда только начинал знакомиться с платформой Windows Phone 7 – решил сразу сделать какое-нибудь приложение или игру. В то время я открыл для себя довольно интересную карточную игру по мотивам MTG – Spectromancer и твердо решил сделать такую же под WP7. Уже не помню по каким причинам (да помню-помню – из-за лени разбираться с XNA) решил писать игру на платформе Silverlight. Различные графические эффекты решил делать при помощи анимации (Visual States) через Expression Blend:
Коварные анимации на Windows Phone

Игру сделал быстро, затем сделал для неё онлайн (где сейчас тусуется в среднем по 50 человек одновременно) и забил (к настоящему моменту её скачали больше чем 200.000 раз). Надеюсь вы не запинаете меня за этот пиар, потому как дальше я объясню главную возникшую проблему и её решение.

Проблема

После того как написал игру и разобрался с WP7, я решил оставить её и заняться чем-то другим. Но тут начали поступать многочисленные жалобы со стороны пользователей о крайней прожорливости до аккумулятора игрой, причем больше всего жаловались обладатели WP8 устройств. Я не обращал на это внимание пока не получил в пользование Lumia 920, которая при игре просто адски нагревалась и быстро сообщала о критическом уровне батареи. На помощь мне пришёл обновленный профайлер, который показывает информацию о Battery consummation для приложения:
Коварные анимации на Windows Phone

И детальную информацию с временной шкалой:
Коварные анимации на Windows Phone

Первым делом меня смутило большое количество обозначений анимаций красного цвета, которые означают, что анимация СPU-bound и выполняется в UI, а не Compositor-потоке (фишка WP, при сильверлайте такого не было):
Коварные анимации на Windows Phone

Эти анимации, нагружая CPU, очень активно потребляют бедную батарейку и приводят к низкой отзывчивости интерфейса. Таким образом, наша цель – развидеть красные сториборды, перекрасив их в синий цвет, заставив выполнятся в Compositor-потоке с аппаратным ускорением видеокарты (хотя есть мнения, что анимация все равно выполняется CPU). «Синии» анимации работают через per-frame callback, таким образом обновляясь с каждым прорисовыванием фрейма.
Не буду подробно описывать как я правил каждую конкретную анимацию в игре, ибо надеюсь, что будет достаточно соблюсти нижеуказанные правила:

  • Не делайте анимации поверх dependency property, которые имеют callback на изменение значения – такие анимации 100% будут выполняться в UI потоке.
  • Не анимируйте свойства, которые приводят к изменению Layout (изменяют свои размеры, отступы и т.п.): Width, Height, Margin, Alignments, etc.
  • Если вам необходимо двигать элемент анимации – анимируйте TranslateTransform.XProperty, но не в коем случае не Canvas.Left – результат одинаковый, но в первом случае анимация будет «синенькая».

Анимация же трансформаций, изменений цвета и некоторых других свойств через DoubleAnimatioin будет выполнятся в том самом Compositor’е.

В качестве заключения посоветую избегать «красненьких» анимаций там, где это возможно, а не забивать на это дело, даже если интерфейс зрительно не тормозит.

Автор: Nagg

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js