Проблемы и нюансы при разработке под SmartTV с использованием React.js

Хочу поделиться опытом разработки приложения с просмотром видео контента для SmartTV (Tizen и WebOS) и с какими проблемами мы столкнулись.

На современных телевизорах, как мы знаем, можно устанавливать разные приложения, для облегчения работы с какими-то ресурсами и контентом. В большинстве случаев, эти приложения под капотом это обычный браузер, на теликах это Chromium.

Так как это браузер, то ничего нам не мешало использовать React.js для разработки, что повлияло на некоторые проблемы с производительностью.

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

Пройдемся по основным моментам:

  1. Ограниченные ресурсы
  2. Навигация
  3. Производительность стилей и рендеринга
  4. Видео плееры
  5. Backend

Ограниченные ресурсы


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

Например для приложения выделяется всего около 250 мегабайт на использование и мы столкнулись с такой проблемой, что при отображении грида с контентом (картинка, описание, рейтинг) могла расходоваться память на пределе, когда в гриде всего 1000 элементов и мы скроллим вниз, то размер картинок увеличивается и увеличивается и в какой-то момент приложение крэшится с надписью, что закончилась память.

Решение этой проблемы react-window
Он не хранит все элементы вне окна в DOM.

Навигация


Если на компьютере мы привыкли, что мы кликаем мышкой по элементам на сайте, то на телевизорах мы пользуемся пультом, который бывает и с возможностью использования как мышь, но в большинстве это кнопки. Отсюда вылазит проблема навигации, что мы должны обрабатывать нажатия кнопок пульта и навигировать по всему приложению без курсора, но, в то же время нам необходимо и обрабатывать нажатия на элементы с помощью «клика».
Некоторые коды кнопок на пультах LG и Samsung отличаются, как и отличаются от клавиатуры обычной, поэтому для каждой платформы у нас были захардкожены коды кнопок, которые мы обрабатываем.

Пример Tizen
Tizen

export default {
  KEY_0: 48,
  KEY_1: 49,
  KEY_2: 50,
  KEY_3: 51,
  KEY_4: 52,
  KEY_5: 53,
  KEY_6: 54,
  KEY_7: 55,
  KEY_8: 56,
  KEY_9: 57,
  KEY_UP: 38,
  KEY_DOWN: 40,
  KEY_LEFT: 37,
  KEY_RIGHT: 39,
  KEY_OK: 13,
  KEY_BACK: 10009,
  KEY_CHANNEL_UP: 427,
  KEY_CHANNEL_DOWN: 428,
  KEY_MEDIA_FAST_FORWARD: 417,
  KEY_MEDIA_PAUSE: 19,
  KEY_MEDIA_PLAY: 415,
  KEY_MEDIA_PLAY_PAUSE: 10252,
  KEY_MEDIA_REWIND: 412,
  KEY_MEDIA_STOP: 413,
  KEY_DEBUG_TOGGLE_CONSOLE: 403,
  KEY_DEBUG_TOGGLE_QUICK_EDIT: 404,
  KEY_DEBUG_SET_FAVOURITES: 405,
  KEY_DEBUG_CLEAR_FAVOURITES: 406,
  KEY_SHOW_REMOTE_POINTER: 7777777, // not applicable
  KEY_HIDE_REMOTE_POINTER: 7777777, // not applicable
};

WebOS

export default {
  KEY_0: 48,
  KEY_1: 49,
  KEY_2: 50,
  KEY_3: 51,
  KEY_4: 52,
  KEY_5: 53,
  KEY_6: 54,
  KEY_7: 55,
  KEY_8: 56,
  KEY_9: 57,
  KEY_UP: 38,
  KEY_DOWN: 40,
  KEY_LEFT: 37,
  KEY_RIGHT: 39,
  KEY_OK: 13,
  KEY_BACK: 461,
  KEY_MEDIA_FAST_FORWARD: 417,
  KEY_MEDIA_PAUSE: 19,
  KEY_MEDIA_PLAY: 415,
  KEY_MEDIA_PLAY_PAUSE: 10252,
  KEY_MEDIA_REWIND: 412,
  KEY_MEDIA_STOP: 413,
  KEY_CHANNEL_UP: 33,
  KEY_CHANNEL_DOWN: 34,
  KEY_DEBUG_SET_EMAIL: 403,
  KEY_DEBUG_TOGGLE_CONSOLE: 404,
  KEY_DEBUG_TOGGLE_QUICK_EDIT: 405,
  KEY_DEBUG_SET_FAVOURITES: 406,
  KEY_DEBUG_CLEAR_FAVOURITES: 407,
  KEY_SHOW_REMOTE_POINTER: 1536,
  KEY_HIDE_REMOTE_POINTER: 1537,
};

Клавиатура

export default {
  KEY_0: 48,
  KEY_1: 49,
  KEY_2: 50,
  KEY_3: 51,
  KEY_4: 52,
  KEY_5: 53,
  KEY_6: 54,
  KEY_7: 55,
  KEY_8: 56,
  KEY_9: 57,
  KEY_UP: 38,
  KEY_DOWN: 40,
  KEY_LEFT: 37,
  KEY_RIGHT: 39,
  KEY_OK: 13,
  KEY_BACK: 8, // backspace
  KEY_MEDIA_FAST_FORWARD: 70, // f
  KEY_MEDIA_PLAY_PAUSE: 80, // p
  KEY_MEDIA_REWIND: 66, // b
  KEY_MEDIA_STOP: 83, // s
  KEY_CHANNEL_UP: 70, // f
  KEY_CHANNEL_DOWN: 71, // g
  KEY_DEBUG_SET_EMAIL: 81, // q
  KEY_DEBUG_TOGGLE_CONSOLE: 87, // w
  KEY_DEBUG_TOGGLE_QUICK_EDIT: 69, // e
  KEY_DEBUG_SET_FAVOURITES: 88, // w
  KEY_DEBUG_CLEAR_FAVOURITES: 82, // r
  KEY_SHOW_REMOTE_POINTER: 7777777, // not applicable
  KEY_HIDE_REMOTE_POINTER: 7777777, // not applicable
};

Как можно заметить, на клавиатуре это кнопки с буквами (в комментариях указаны).

Для того, чтоб обрабатывать навигацию через нажатие кнопок и нажатие мышью, у нас результатом был всегда один event — mouseClick, тем самым мы одинаково обрабатывали все события.

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

Производительность стилей и рендера


Анимация на CSS работает медленно на телевизорах, особенно, когда DOM элементов, которые попадают в анимирование много, можно увидеть не плавное изменение а слайд-шоу. Один из вариантов решение этой проблемы — canvas. Отрисовка на нем, анимация, подсветка при навигировании ускоряют работу в разы, но, если у вас есть автоматизаторы, то им такая реализация может не понравиться, т.к им сложно по картинке проверять контент.

Много перерендереваний на странице — еще одна боль, все начинает тормозить, дергаться. Нужно было максимально контролировать этот процесс, после чего shouldComponentUpdate компонентов выглядит так:

image

В итоге переписали чувствительные части приложения на vanilla js, стало быстрее.

Видео плееры


У LG и Samsung разные видео плееры, что тоже создает дополнительные трудности при разработке. Для LG используется video-тег, для Samsung AVPlay sdk. Поэтому есть отличия в функциональности, нужно учитывать, что не все возможности одинаковы и могут отличаться от версии к версии ОС.

Также  были проблемы с нагрузкой при запуске видео — решалось кэшированием, параллелизацией и откладыванием запросов, обработок.

Backend


На скорость работы влияет качество бэкенда, скорость обработки запросов и их количество. На стороне FE должно быть минимальное количество обработки данных. Если нужно подгружать большие объемы даных, можно использовать web workers.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 19

    0
    После прочтения статьи появляется вопрос, почему для телевизоров пишут на web-технологиях, если там так мало ресурсов? Больше подошло бы что-то вроде Qt.
      0
      После прочтения статьи появляется вопрос, почему для телевизоров пишут на web-технологиях

      Скорее уж появляется вопрос — почему на медленных и ресурсоёмких веб-технологиях? Реакт с его виртуальным DOM, серьезно? А между реактом и vanilla.js прям вообще ничего нет?
        0
        Тут приводится проблемы конкретно для React.js, это естественно не единственный способ реализации приложения для телевизоров :) А что между реактом и ванилой вы предлагаете?
          +2
          А что между реактом и ванилой вы предлагаете?

          svelte.dev

          mustlab.ru/ru судя по докладам и статьям PaulMaly уже несколько лет успешно используют svelte для разработки под ТВ.
            0
            спасибо, почитаю
            +2
            А что между реактом и ванилой вы предлагаете?

            Всё, что левее реакта. Там конечно далеко не всё предлагает высокую степень абстрагирования от деталей, но там много и высокоуровневых фреймворков. Да тот же даже preact намного быстрее и тоньше. И про svelte уже сказали — тут как раз отличный кейс для неё, да.
          0
          Tizen позволяет писать на .net, WebOS не вижу такой поддержки. Основная идея была — переиспользование кода между разными ОС теликов и использование общей sdk для web части
          0
          В большинстве случаев, эти приложения под капотом это обычный браузер, на теликах это Chromium

          Что понимается под «большинством случаев»? Например, на моем LG 32" (Smart) стоит именно Chrome, причем ну очень старенький, 28-ая версия.
          +1
          Если позволите, еще дополню ссылками. В jsunderhood была неделя разработчика под смарт тв. Архива нет, но вот несколько веток с интересными особенностями такой разработки:

          twitter.com/jsunderhood/status/1172215584303570945
          про выкладывание в сторы

          twitter.com/jsunderhood/status/1172224195536838656
          про написание приложений под тв

          twitter.com/jsunderhood/status/1172194802076663808
          на что похожа разработка под смарт тв
            0
            Подскажите, а какой плеер вы использовали для webOs, какой там SDK?
              0
              Для WebOS использовался HTML5 тег video и работа велась с ним.
              Для взаимодействия с WebOS использовалась Web API webostv.developer.lge.com/api/webostvjs/webos

              Для Tizen использовался AVPlay developer.samsung.com/tv/develop/guides/multimedia/media-playback/using-avplay
                0

                Тогда все-таки в статье не совсем корректно указано, что и у LG и у Samsung разные нативные видео плееры с разным sdk. Насколько я знаю, у LG нет аналога самсунговского AVPlay и все играется только через video-тег.

                  +1
                  Спасибо, исправил
              0
              Маловато. Не очень понимаю в чем цель статьи?
              Вы перечислили несколько проблем, ок. Но никаких выводов, никаких интересных поворотов.
              Тоже что ли пойти написать статью как я вчера вебпак настраивал.
                0

                Дополню еще ссылкой на подборку awesome-smart-tv, где собраны полезные библиотеки и фреймворки для смартов.


                Кстати, в контексте статьи было бы интересно узнать, пробовали ли вы react-tv? Кажется там некоторые тв-специфичные проблемы должны быть решены.

                  +1
                  Спасибо за ссылку.
                  На практике не пробовали react-tv, но есть и + и -, поддержка только webOS, ну и использование не проверенной библиотеки на enterprise проектах чревато. Когда разработка стартовала, на тот момент react-tv только появился и был сыроват.
                  А так да, он решает многие проблемы, может у кого был практический опыт использования react-tv?
                  +1
                  Для меня главным ограничением в Tizen стала древняя версия Chromium, которая имеет проблемы с поддержкой многих вещей, к которым мы давно привыкли в современных браузерах. У Samsung все ОЧЕНЬ ПЛОХО с обновлениями SmartTV: большинство продающихся на рынке телевизоров работают на версии Tizen, которую не поддерживает их-же собственный SDK. И обновить их нельзя. Ну и React там, конечено, совсем не нужен.
                    0

                    Приставочку на андроид прикупить дешевле. Хотя на моем Самсунге Ютуб и нетфликс более менее работают из коробки.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое