GrabDuck

Рекомендации по разработке приложений для STB MAG на WebKit

:

Краткое описание

Любое приложение, которое создается для работы на приставке MAG, представляет собой обычную HTML-страницу. На этой странице с помощью JavaScript происходит обработка нажатий клавиш пульта/клавиатуры и выполнение соответствующих действий. Для работы с видео используются методы JavaScript API.

Представление Приложения в качестве HTML-страницы позволяет воспринимать работу с приложениями как работу с обычным сайтом. Также это позволяет использовать стандартный набор средств для web разработки (любая IDE, DevTools и т.д.).

JavaScript API

Общее описание работы с API и плеером, пример простого приложения и частично устаревшая документация по JavaScript API находится в pdf-файле Спецификация JavaScript API (pdf).
Более актуальная документация к методам JavaScript API находится здесь.
Документация по работе с приставками MAG находится здесь.

Особенности используемого ПО

Приложение на приставке выполняется в браузере, работающим на движке WebKit. Поскольку работа с приставкой имеет свои особенности, движок модифицирован для обеспечения необходимого функционала при максимальной скорости работы. Как результат, некоторые из новых технологий и глобальных объектов, присутствующих в современных десктопных браузерах, недоступны (например, свойство classList, технология flash) либо поддерживаются частично (HTML5).

Требования к приложению

Крайне важно обеспечить стабильную работу и приемлемую скорость работы интерфейса при создании приложения. Поэтому новые приложения проходят обязательное тестирование на соответствие требованиям перед помещением их в каталог приложений. Это связано с тем, что целый ряд распространенных на сегодняшний день моделей приставок имеют крайне ограниченные ресурсы (по сравнению с ПК). Как результат, при отсутствии оптимизации приложение может работать крайне медленно либо не работать совсем.

Оптимизация JavaScript кода

Перед началом разработки приложения необходимо осторожно подойти к выбору используемых фреймворков и библиотек. Обычно библиотеки/фреймворки предназначены для работы в десктопных браузерах. С их помощью устраняются недочеты, возникающие при работе в разных браузерах. Также библиотеки/фреймворки сильно облегчают саму разработку приложения, предоставляют удобные универсальные обертки и абстракции. Накладные расходы такой универсальности практически незаметны для ПК, но крайне болезненны для ряда моделей приставок.
В качестве примера можно рассмотреть такую универсальную высокоуровневую библиотеку как jQuery. Хотя эти же проблемы есть у большинства современных фреймворков и других библиотек. Практически каждый вызов методов данной библиотеки влечет за собой выполнение множества функций. Эти функции призваны поддержать необходимый уровень абстракции, удобный функционал, предупредить часть ошибок и устранить проблемы, возникающие при работе в разных браузерах или браузерах разных версий.
На практике, разница в скорости и количестве задействованного кода при поиске DOM элемента в документе выглядит так:

  Сравнение

Учитывая специфику платформы будущего приложения, такой функционал излишен и вполне может быть заменен более быстрыми методами. В качестве примера можно рассмотреть следующую сравнительную таблицу: http://youmightnotneedjquery.com 

Как один из вариантов решения данной ситуации, рекомендуем воспользоваться для разработки приложения нашим фреймворком: https://github.com/DarkPark/stb (готовое приложение, демонстрирующее работу основных компонентов https://github.com/DarkPark/stb-demo).

Непосредственно в коде важно стараться оптимизировать алгоритмы. Например:

  • Использование директивы “use strict”. Это не только поможет в оптимизации работы кода, но и предупредит о возможных ошибках. Описание работы директивы.
  • Использование кеширования результатов работы с DOM, если в будущем предполагается еще работа с найденным элементом. Тем самым отпадает необходимость в повторном поиске по дереву DOM уже найденного ранее элемента.
  • Завершение работы цикла с помощью break при достижении результата вычисления. Поскольку зачастую дальнейшая работа цикла бессмысленна и просто впустую расходует ресурсы. 
  • Объединение несколько условий “if” с помощью логических операций, где это возможно, что позволяет избежать лишних проверок.
  • Использование querySelector, children, parentNode, addEventListener и многих других свойств, предоставляемых браузером. Поскольку обычно они имеют куда большую скорость работы чем их мультибраузерные и мультиверсионные JavaScript аналоги. Пример.  
  • Использование цикла “for” или «while» вместо “forEach” для больших массивов (>1000 элементов). Поскольку отсутствие расходов на вызов функции, в некоторых случаях, может привести к существенному повышению скорости работы на большом количестве итераций.
  • Использование замыканий для того, чтобы не засорять глобальную область видимости, а так же облегчить работу сборщику мусора по очистке уже ненужных данных. Тем самым освобождаются ресурсы приставки.
  • Использование в коде строгого сравнения. Это избавляет от необходимости выполнения приведения типов при каждой операции сравнения:
    “a === b” вместо “a == b”
  • Использование  для создания DOM элементов метода document.createElement вместо присваивания HTML в innerHTML свойства.
  • Использование для массового добавления DOM-элементов промежуточного DocumentFragment. Это избавит от изменения всего DOM при каждом добавлении нового элемента. После добавления в DOM, DocumentFragment исчезнет, а вместо него вставятся его дети.
  • Использование готовых наборов классов вместо изменения style.* свойств «на лету».

Чтобы ознакомиться с правилами стиля и советами по написанию кода, которые мы используем, пойдите по ссылке https://github.com/DarkPark/jscs.

Интерфейс

При создании интерфейса, желательно обратить внимание на несколько моментов, которые могут повлиять на скорость и плавность его работы:

  • Перерисовка страницы браузером происходит только после завершения потока JavaScript вычислений. Например, если в цикле выполнять изменения в стилях HTML страницы, то визуально они применятся только по завершению цикла, все сразу.
  • При выполнении сложных вычислений скорость работы приложения может падать. Если в такие моменты на экране имеются анимации, то они будут подвисать или отображаться рывками. Сложные анимации теряют плавность и при малых нагрузках.

Общая оптимизация

Помимо кода важна так же оптимизация используемых ресурсов.
В графике должны быть использованы оптимизированные картинки. Слишком большие или тяжелые картинки потребуют большое количество ресурсов для обработки, что в свою очередь вызовет падение скорости работы приложения. Также желательно использовать в приложении картинки в их оригинальном размере, поскольку их масштабирование также занимает время и ресурсы. Очень нежелательно использовать растиражированные однопиксельные изображения для фонов.

Браузеру требуется время для подгрузки и анализа необходимых ресурсов при загрузке приложения. Можно уменьшить это время, если в релизной версии минифицировать код и CSS. Также желательно использовать модульный подход (CommonJS) построения приложения, что позволит удобно разбить логику приложения на логические блоки.
Объединение файлов желательно применять и к CSS.

При большом количестве маленьких картинок (например иконки), их можно объединить в спрайты либо, если они достаточно просты, - в отдельный шрифт.
В целом, уменьшение количества подгружаемых файлов уменьшает время запуска приложения в браузере.