Рекомендации по разработке приложений для STB Linux&WebKit
Краткое описание
Любое приложение, которое создается для работы на приставке MAG, представляет собой обычную HTML-страницу. На этой странице с помощью JavaScript происходит обработка нажатий клавиш пульта/клавиатуры и выполнение соответствующих действий. Для работы с видео используются методы JavaScript API.
Представление Приложения в качестве HTML-страницы позволяет воспринимать работу с приложениями как работу с обычным сайтом. Также это позволяет использовать стандартный набор средств для web разработки (любая IDE, DevTools и т.д.).
JavaScript API
Общее описание работы с API и плеером, пример простого приложения и частично устаревшая документация по JavaScript API находится в pdf-файле Спецификация JavaScript API (для версий ПО до 0.2.18).
Последняя версия документации к методам JavaScript API находится Спецификация JavaScript API (для версий ПО 0.2.18 и выше).
Документация по работе с приставками 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.
При большом количестве маленьких картинок (например иконки), их можно объединить в спрайты либо, если они достаточно просты, - в отдельный шрифт.
В целом, уменьшение количества подгружаемых файлов уменьшает время запуска приложения в браузере.