Интерес к WebAssembly велик, но пока что нечасто встретишь людей, использующих эту технологию в рабочем проекте. Разработка приложений под Smart TV — тоже «нетипичный JavaScript», когда все слышали о чём-то, но немногие лично пробовали.
А у Андрея andreynagih Нагих есть опыт в обеих сферах: ранее он занимался Smart TV-приложениями проекта Peers.TV, а в последние месяцы так плотно знакомился с WebAssembly, что в итоге сделал доклад об этом на нашей конференции HolyJS. И в онлайн-трансляции HolyJS мы поспрашивали его и о том, и о другом.
А теперь решили, что читателям Хабра это тоже может быть интересно, и сделали отредактированную текстовую версию интервью.
(Если кому-то удобнее видеоформат, вместо чтения поста можете посмотреть исходное видео.)
Евгений phillennium Трифонов: Вы выступили здесь с докладом о WebAssembly — много ли было зрительских вопросов, и были ли они от «теоретически интересующихся», или уже нашлись практически использующие?
Андрей Нагих: После доклада целый час отвечал в дискуссионной зоне на совершенно разные вопросы, я удивлён, что их было так много по всему спектру. В основном вопросы были от тех, кому пока «просто интересно», но были и люди, которые уже используют. Что удивительно, потому что таких людей пока мало. Были вполне практические вопросы.
Евгений: Раньше про WebAssembly говорили «поскорее бы это дозрело и стало применимо». А сейчас технология насколько «дозревшая»?
Андрей: Сама технология уже вполне рабочая, можно использовать в продакшне. Мы вот используем. Но проблема с инструментами. Сам компилятор достаточно неплох, так как оказался старше самой технологии — он доступен с предыдущей версии, с asm.js. Но инструменты отладки, source maps, дебаггер — с этим пока тяжело. Я думаю, в ближайшие год-два браузеры будут подтягивать эти моменты.
Евгений: А из-за чего вам изначально понадобился WebAssembly — что за проект, и в чём там выгода от этого?
Андрей: Один из наших проектов, ByteFog — технология по P2P-доставке видеоконтента. У нас, наверное, самый идеальный юзкейс, который только можно придумать для WebAssembly. У нас уже была большая кодовая база на C++, мы не хотели переписывать её на какой-то другой язык, и она была нам нужна в браузере. Поэтому эта технология, кажется, подходит здесь стопроцентно.
Сначала мы подумали, что возьмём, просто скомпилируем и всё заработает. Но, конечно, так в жизни не бывает, поэтому и родился этот доклад о граблях и, собственно, о том, как это всё затащить в продакшн.
Олег olegchir Чирухин: И какие главные проблемы возникли?
Андрей: Самая главная проблема в том, что у нас нет доступа к системе. У нас было нативное приложение, оно могло делать всё, что угодно. Когда мы портируем его в браузер, мы не можем делать ничего за рамками JavaScript. И с этим надо как-то жить, нужно использовать браузерные API.
Процесс портирования нашего приложения занял, условно, восемь месяцев. Правда, за этот период мы сделали неплохой рефакторинг нашей кодовой базы, что, в общем-то, хорошо. И теперь мы можем портировать её ещё куда-нибудь.
Олег: Уже упоминался тулинг, а можно поподробнее? Отладка, трассировка, профайлинг, вот это всё.
Андрей: Если коротко — всё плохо. Но появляются небольшие вспышки хороших вещей.
Ну, с компилятором более-менее утряслось: это Emscripten (я говорю про С++, в других рантаймах — Rust, Go, Kotlin/Native — по-другому).
Отладка: Firefox поддерживает source maps, что уже само по себе неплохо. Google Chrome просто позволяет видеть ассемблерный код, там можно ставить точки остановки, но это так себе.
Профайлер работает, в Firefox получше, в Chrome чуть похуже. Разница в том, что Firefox разматывает имена, то есть делает их такими, какие они в исходном коде. Chrome показывает мангленные имена, и надо прищуриваться, чтобы понимать, что там такое.
Олег: А как происходит адаптация людей из JavaScript к C++ и наоборот?
Андрей: Наверное, можно вот на меня посмотреть — изначально фронтендер, который теперь притронулся к нативному коду. Но, честно говоря, у меня и до проекта было желание попробовать что-то пописать нативно. Так что, наверное, я не очень репрезентативен.
Мы с моим коллегой Юрой, который выступает в проекте со стороны C++, много общались: он мне рассказывал про «плюсы», я ему — про JavaScript. А он интересовался JavaScript. Совпадение — десять из десяти: нативщик хочет JavaScript изучить, когда такое было? И у нас сложилась неплохая команда.
Есть ещё третий человек — это Коля, архитектор, который вообще посмотрел на ассемблерный код и сказал: «Ребята, да тут и так можно отлаживать. Вот же, смотрите, всё понятно: это стековая машина, тут мы с памятью работаем, тут арифметика… ребята, зачем нам source maps?» Ну, он умеет писать под embedded-системы, в свободное от работы время это делает.
Олег: А у тебя возникли какие-то особые удивления от C++: от языка, от юзабилити, работы с ним?
Андрей: Ну я, конечно, был готов к этому. Самое главное удивление в том, что, пообщавшись за время проекта с плюсовиками, мы поняли, что у JS и C++ очень много общего. Казалось бы, совершенно разные языки, но можно найти точки пересечения. На эту тему даже можно сделать отдельный доклад, надо будет подумать об этом.
Евгений: А теперь, после того и другого, на чём хочется писать дальше?
Андрей: На самом деле, я не готов писать в продакшн на C++. Я бы поделал на нём что-то для себя. Ну а JavaScript — куда же он денется?
Олег: А что насчёт того, что C++ быстрый, и с кучей прикольных фич вроде шаблонов? Шаблоны не могли бы помочь во фронтенде при написании какого-нибудь суперстандартного кода?
Андрей: Есть такая шутка: «если у вас есть проблема и вы хотите решить ее с помощью регулярного выражения, то поздравляем, у вас теперь две проблемы». У меня есть ощущение, что с шаблонами что-то похожее. В нашем проекте мы стараемся не использовать шаблоны, архитектор очень сопротивляется, когда разработчики C++ пытаются что-то туда внедрить. Проблема возникает с отладкой: никогда не понятно, где конкретно бахнуло.
Олег: То есть непонятно, что происходит в том коде, который сгенерился? Он не может построить source map до исходника?
Андрей: Насколько я знаю, даже в нативном C++ с шаблонами отладка тяжёлая. Когда мы это затащим ещё и под WebAssembly, у нас наложатся проблемы с отладкой под WebAssembly. Поэтому я думаю, это вообще будет ад. (внимательно смотрит в камеру) Дети, не используйте шаблоны C++!
Олег: Без шаблонов он же в С превратится. Можно будет писать на чистом С.
Андрей: А как же объекты?
Олег: Ну… «Си с классами», да. Просто я думаю, что написание кода на С с классами и на идиоматическом C++ с шаблонами — это два совершенно разных метода.
Андрей: Да, возможно.
Олег: Философский вопрос: а ты не думаешь, что, когда к браузерам добавляют WebAssembly, открывается портал в ад?
Андрей: Похоже на то. Потому что сейчас, наверное, будет модно взять любую из библиотек или программ на C++, которые понаписали за всё время существования C++, попробовать скомпилировать её в браузере и посмотреть, что получится. Я сегодня показывал демку Windows 2000 в браузере.
Олег: В смысле, это прямо полноценная Windows 2000?
Андрей: Да, это та самая Windows 2000, которая была 18 лет назад и которой нужен был целый компьютер для запуска — а сейчас ей достаточно Chrome.
Олег: А что там с вещами, которые требуют kernel mode, вот это всё?
Андрей: Она бегает в эмуляторе QEMU, причём портированном под WebAssembly лично Фабрисом Белларом (автором QEMU). Там, конечно, нельзя получить доступ к файловой системе, к сети. Но это Windows 2000, она запускается, пиликает, и там всё есть. Можно посмотреть.
Олег: Перейдём к теме приложений под Smart TV. Вот, кстати, с WebAssembly там можно что-то интересное сделать?
Андрей: Можно было бы, если бы он там поддерживался. Со Smart TV какая проблема? Эта разработка — как будто разработка фронтенда десять лет назад, потому что Smart TV не обновляются. Человек купил телевизор, повесил на стену, и он висит там годами.
Олег: Но у меня там постоянно «подождите, загружается прошивка». Аж бесит.
Андрей: Прошивка, может, и загружается, но, насколько я знаю, она не обновляет прямо систему, браузер. В итоге мы до сих пор поддерживаем телевизоры многолетней давности, на которых браузер представляется как Chrome 5.
Олег: Я даже не помню такой.
Андрей: Я тоже не помню. Разработка под Smart TV, особенно старые — это такое минное поле, похожее на фронтенд времён войны браузеров.
Олег: То есть приходилось делать супер-кроссбраузерную вёрстку, которая будет работать и на древних версиях, и на новых?
Андрей: Да. Там на самом деле проблема не столько с вёрсткой, сколько с JavaScript — несовместимости по API, сейчас уже не упомню всего.
Олег: А что ещё из доступного в браузерах хочется использовать на Smart TV, но нельзя?
Андрей: Миллион вещей, начиная с флексов (это даже не JavaScript) и заканчивая WebRTC. ByteFog использует WebRTC. Как было бы прекрасно, если бы мы затащили в Smart TV тот код, который у нас уже есть…
Евгений: А помимо упомянутой проблемы, разработка под Smart TV — каково это вообще? Какие были ощущения?
Андрей: Иногда складывалось ощущение, что разработчики браузеров Smart TV недолюбливают программистов, которые разрабатывают приложения под Smart TV, потому что средства отладки были очень плохими, их практически не было. Это не касается современных платформ Tizen и webOS, там сделали лучше. Но я занимался этим ранее, тогда были старые платформы, и там всё было плохо. Лучшим средством отладки был weinre, который на самом деле не является дебаггером — там нельзя остановить JavaScript; это такой порт Chrome DevTools, который работает по веб-сокетам. В общем, там можно было отлаживать верстку, но с JavaScript практически ничего нельзя было сделать. Как-то так мы и жили.
Олег: А зачем вообще отлаживать на самом Smart TV, если можно в браузере запустить?
Андрей: В браузере у нас есть JavaScript и есть API, который даёт нам браузер. Это две разные вещи. Точно так же в телевизоре у нас есть JavaScript, у нас есть API от движка браузера…
Олег: Скорее всего, это WebKit.
Андрей: Да, как правило. И есть ещё одна категория API — те, которые предоставляет платформа этого телевизора. В первую очередь это плеер, затем другие возможности — управление с пульта и так далее. Этих API в браузере не будет.
Есть эмуляторы, производители действительно их предоставляют, но они не полностью соответствуют железу. Поэтому не факт, что отлаженное на эмуляторе заработает на телевизоре. И наоборот: на эмуляторе может не работать, а на телевизоре будет прекрасно бежать. Так что в конечном итоге мы пришли к тому, что не используем эмуляторы, а стараемся отлаживать на реальном железе. Получается быстрее: ты не тратишь время на баги, которых нет.
Олег: А с каким количеством платформ приходилось иметь дело, и со временем их становилось меньше или больше?
Андрей: Когда я занимался Smart TV, произошёл переход производителей от старых операционных систем, которые условно назывались Linux и были у каждого под каким-то своим соусом, к новым. Тогда нам приходилось писать три разных приложения — под Samsung, LG и Panasonic. Эти приложения, условно говоря, копипастили код. И затем практически одновременно выходят новости, что Samsung переходит на Tizen, LG — на webOS, а Panasonic на Firefox OS (после этого она не выжила, и у Panasonic теперь форк).
В общем, казалось бы, все меняют платформу — почему бы не сойтись на какой-то одной? Это же было бы гораздо лучше для всех, особенно для разработчиков: было бы больше софта, пользователи получили бы больше полезных программ. Но нет, мы всё равно пишем разные приложения.
Олег: А можно как-то заполифиллить на все платформы?
Андрей: Ну, в итоге мы пришли к единому фреймворку, подставляем платформозависимые вещи и стараемся писать кроссплатформенную бизнес-логику. Но, кажется, этого можно было бы избежать.
Олег: А ещё же есть и Android-телевизоры?
Андрей: Есть, причём двух видов. Раньше как делали? Вставляли обычный Android в телевизор, и пусть едет. А потом Google сделал специальную ветку Android TV, лучше оптимизированную для D-Pad, то есть управления с пульта. Есть и такие телевизоры. Но это отдельная история и отдельный магазин.
И если в мобильных устройствах Android всех победил и самые разные производители остановились на этой ОС, то с телевизорами у Google этого не получилось сделать. Вместо того, чтобы все ограничились одной платформой, их стало ещё на одну больше, как на картинке xkcd.
Евгений: У меня дома телевизор под Android TV с 4K-экраном, но с HDMI-входа он действительно принимает 4K, а вот встроенный Android там в 720p. Почему так происходит? Поскольку телевизор по 4K-меркам бюджетный, вероятно, производитель сэкономил на железе?
Андрей: Да, я думаю, здесь они упираются в то, что операционная система не может на этом железе отрендерить 4K-картинку. На самом деле, это распространённая ситуация, когда Smart TV (то есть та часть в телевизоре, которая идёт из приложений), не использует полное разрешение экрана. FullHD просаживалось до HD Ready, 4K — до FullHD или даже до 720p. Это такой интересный момент, когда мы не можем показать 4K-контент на 4K-телевизоре, хотя у нас есть и телевизор, и контент.
У телевизоров вообще нередко подлагивает интерфейс — это, к сожалению, бич Smart TV-платформ. Причём на Яндекс.Маркете не поставить галочку «телевизор, который не будет тормозить» и отфильтровать. Видимо, остаётся приходить в магазин и там выбирать.
Олег: А как это сказывается на разработке приложений? Если ты добавляешь много div-ов, то приложение становится всё медленнее и медленнее?
Андрей: Конечно. Если надо отрендерить большой список, то приходится извращаться и рендерить его не весь, а по частям. У нас в списке каналов их могло быть двести, и мы не могли отрендерить список целиком — у него тогда возникали тормоза при скроллинге.
Я тут говорю про ситуацию пару лет назад. На телевизорах, которые выпускают сейчас, всё может быть гораздо лучше. Но, опять же, люди нечасто меняют телевизоры.
Олег: А как думаешь, какое будущее у всего того, что мы сейчас видим в Smart TV?
Андрей: Я пессимистично настроен. Надеюсь, мой прогноз не оправдается, но мы видели закат технологии 3D на телевизорах, когда все производители сказали: «Ладно, никто это не покупает, это не является ключевым фактором при выборе устройства». Такое ощущение, что Smart TV может постичь эта участь, хотя мне бы не хотелось.
Олег: А какой тогда основной паттерн использования этой штуки, если у тебя нет Smart TV? Взять большой жирный РС и воткнуть в телевизор?
Андрей: Большой компьютер, я думаю, никто не будет втыкать. Может быть, приставки будут лучшим выбором, но у Smart TV и приставок есть одна общая черта: управление с пульта. И сделать хорошее управление с пульта очень сложно. Порой делают джойстики с акселерометром, то есть реализуют управление жестами, или эмулируют мышь, но это тоже далеко от идеала. В общем, проблема со Smart TV лежит скорее в области UI/UX. Отчасти телевизионному UX может помочь голосовое управление — у нас в Peers.TV оно поддерживается с помощью смартфона пользователя, а сейчас работаем над специальным пультом с микрофоном.
Евгений: Да, я вижу, что и Google старательно ведёт ТВ в сторону голосового управления. Пока это происходит с переменным успехом. Но завершим тогда разговор так: будем надеяться, что в каком-нибудь будущем нашим зрителям достаточно будет сказать «запусти мне трансляцию HolyJS»!
Если у вас при чтении возникли какие-то вопросы про WebAssembly или Smart TV, задавайте их Андрею в комментариях.
А также обращаем внимание, что 24-25 мая в Петербурге пройдёт следующая HolyJS. Её программа ещё не объявлена, но там наверняка тоже найдётся место «нетипичному джаваскрипту», выходящему за рамки привычного фронтенда — а билеты постепенно дорожают.