Недавно я совершенно случайно наткнулся на простую рекламную заметочку "Neutralinojs — альтернатива Electron, потребляющая меньше памяти", рассказывающую о том, что есть такая крутая вещь как Neutralinojs. Заметочка, как и следует ей быть, совсем короткая и не несёт никакой полезной информации, кроме рекламного лозунга "Лучше чем <что-то популярное>!"
Примерно понимая как работает Electron и NW.js и не найдя совершенно никакого упоминания о принципе работы этого нового и суперкрутого "чудо-зверя" в заметке, я начал исследования.
Собственно представляю вниманию результаты своего микро-исследования!
Так как любую новую технологию я рассматриваю как возможный инструмент, то я сразу задал несколько вопросов:
- Почему оно ест в разы меньше памяти?
- Какие даёт ещё плюшки?
- Для чего мне это чудо использовать?
Почему не жрём память?
Покопавшись в исходниках и двух достаточно информативных картинках об архитектуре, я понял, что этот проект работает именно по тому самому UNIX Way, который любят все линуксоиды. Философия проекта проста: зачем придумывать новый велосипед, если можно использовать уже готовый?
В чём минусы Electron:
- Тащим с собой Chrome
- Тащим с собой Node.js
- Тащим с собой прослойку, чтобы два предыдущих работали вместе
Вместо этого всего сделано так:
- Мы не тащим Chrome
- Мы не тащим Node.js
- Мы тащим только прослойку между каким-то браузером и какой-то ОС
Давайте посмотрим как конкретно это реализовано.
Архитектура
Весь проект состоит из 2 частей: сервера и клиента.
Сервер запускается сразу и является настоящим партизаном в тылу ОС. Он умеет хранить данные, открывать файлы, писать в файлы, запускать крипторы shell-команды. Собственно он делает всё, что может понадобиться, предоставляет API для операционки и общается с помощью HTTP с клиентом. Так же он отдаёт клиенту всё, что тот должен отобразить на экране. Достаточно стандартная функциональность для сервера.
Для каждой операционной системы был форкнут и доработан напильником свой сервер на C++. Под Mac пока не нашли что форкнуть, поэтому и поддержки нет.
Клиентов может быть 3 типа:
cloud
— Любая программа, знающая порт, на котором работает сервер, может исполнять командыbrowser
— Сервер сам запускает процесс стандартного системного браузера с нужным URL. Тут сервер требует уже специальный TOKEN, который сам вставляет в отдаваемые HTML странички.window
— Сервер запускает специальный render процесс, который просто отображает системный WebView. Тут тоже нужен токен
Тут нужно отметить, что сервер может работать одновременно только с одним типом клиента, и указать тип клиента нужно в конфиге с помощью поля mode
.
Как видите, ничего лишнего. Само по себе приложение на этом "фреймворке" состоит из исходников, которые получаются клиентом как статика, и собственно сервера, который умеет натравливать либо браузер, либо WebView на необходимый URL. Вот что значит истинный DRY!
Какие плюшки?
Из плюшек, конечно же, меньшее потребление памяти. Так как не несётся с собой ни Node.js, ни Chrome, доставляемые клиенту данные очень малы в объёме. Так же разработчики настаивают, что не нужно качать какие-то непонятные builder'ы, не нужно тратить время на компиляцию и всё такое.
Собственно из плюсов это всё, теперь перейдём к минусам.
Сразу хочу оговориться, что проект очень молодой, живёт чуть более 5 месяцев, но он уже гордо носит версию 1.1.0, так что считаю, что имею право оценивать продукт как уже готовый, и предъявлять ему требования такие же, как и к конкурентам.
Болячки NW.js
Тут у нас сразу веер проблем, которые мягко перекочевали из NW.js.
Первое, и самое заметное для пользователя — поставка приложения. Чтобы клиент запустил у себя на компе нашу программку, ему нужно иметь 2 главные вещи: neutralino.exe
и папку app/
. Внутри папки хранятся все настройки (вроде режима работы сервера и заголовка окна) и собственно index.html
, который отдаётся клиенту. Самый простой способ — это дать пользователю zip-архив и сказать на какую програмку тыкать, но пользователи всё равно найдут, что сделать не так, как в инструкции и что сломать.
Для решения этой проблемы в NW был создан builder, который умел упаковывать всё в exe, вместе с ICO и архивами. Менее очевидным решением были SFX архивы, но на них в принципе косо смотрят антивирусы, так что тоже не очень хороший вариант. Сами разработчики планируют всё же сделать свой packer, но пока о нём только слухи ходят.
Вторая проблема заключается в точке входа. Это всегда index.html
. Вы не можете ничего с этим сделать и даже указать другой файл. Все скрипты, которые нужны приложению, должны быть загружены в этом index.html
. Проблема не сильно большая, но гибкость системы это уменьшает в разы.
Какой-то браузер
Тут всё ещё хуже, чем у NW.js или Electron. Если в последних мы точно знаем версию браузера, который будет отображать наше приложение, то тут мы в принципе не можем быть уверены, что ОС предоставит нам WebView, умеющий работать с JS. То есть мы возвращаемся в лихие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows.
Это ограничивает наше приложение в части отображения и проигрывания каких-нибудь медиа файлов, а это основная функция приложений, разработанных по принципу "Web for Desktop".
API
Поскольку авторы стремятся к минимализму, то предоставляемый сервером API не отличается разнообразием методов. Я бы даже сказал не отличается продуманностью. Всё это небуйство описано в такой же скудной документации.
Единственный, кто умеет общаться с системой — Neutralino сервер, то мы должны как-то общаться с ним. Канал связи односторонний — HTTP. По сути все, что нам дают использовать в JS — просто wrapper вокруг REST API сервера.
Весь API можно поделить на 3 части: работа со Storage, сильно базовая работа с FS (только читать, удалять и создавать — никаких излишеств) и вызов системных окон и команд.
А теперь пробежимся по самому дизайну API, доступному из JS.
Начнём с callback'ов. Так как браузер у нас какой-то, то и ES5, а соответственно и Promise, использовать не получится. А так как Node.js разработчики на дух не переносят, то и Node-like колбеки использовать они не хотят. Поэтому у каждого метода есть 2 колбека: один для результата, а другой для обработки ошибок, формат которых, кстати, не известен.
На счёт результатов: у большинства команд, например, работающих с OS, в колбек передаётся объект с полем stdout
, внутри которого находится строка. Как вы уже поняли, читать файлы большого объёма и тем более обрабатывать их в каком-нибудь Buffer-like объекте не получится. У системных окон результат в другом формате, там используется объект с полем file
. Вопрос "почему же в принципе нужны объекты с одним полем" остаётся не отвеченным.
А теперь перейдём к Storage. В нём есть такие сущности как bucket'ы, которые сохраняются как JSON-файлы рядом с исходниками приложения. При этом, чтобы записать данные в какой-то bucket, мы должны передать объект, с именем bucket'а и его новым содержимым. Чтобы получить данные, передаём только строку — имя bucket'а. Никакого намёка на схожесть со стандартным Storage интерфейсом, зачем, делаем свой велосипед...
Ну и давайте немного про интеграцию с ОС. Вспомним, что Electron и даже NW предлагали возможность создания своих Context Menu, разрешали скрывать окно и даже создавать иконку в трее. Тут этого всего просто нет. И, учитывая архитектуру решения, никогда не будет. Только браузер и только REST API, только хардкор.
Для чего можно использовать?
Я долгое время считал, что если нужно просто перенести форму регистрации из сайта в десктопное приложение, то можно использовать NW.js и не париться. Если нужно что-то посложнее, что-то, что требует интеграции с системой в графическом плане, то это Electron. Да, у каждого свои минусы, но это уже хоть какие-то продукты, на которых можно делать своё приложение.
Но Netralinojs тоже можно использовать. Например, какой-нибудь чатик будет работать достаточно неплохо, только на сервере надо будет настроить CORS. Какой-нибудь маленький графический генератор текстовых конфигов будет вполне себе хорош. Для себя я вижу этот фреймворк только как платформу для маленьких утилит с графическим интерфейсом, которые нужно будет запускать не часто и не на долго. Думаю вы тоже можете вспомнить из своей профессиональной деятельности хотя бы один маленький продукт, который бы мог работать на столь минималистичной платформе.
Вывод
Фреймворк на самом деле очень и очень сырой. Его минимализм может быть его сильной стороной, но как только потребуются фичи, которые выходят за рамки API, то придётся переходить либо на Electron, либо на NW.js.
Я очень надеюсь, что v1.1.0 — не последняя, и что разработчики ещё переделают многие огрехи в дизайне своего API и предоставят более гибкие возможности по настройке и поведению приложения. Так же надеюсь, что они всё же найдут статический сервер на плюсах, который можно было бы форкнуть и использовать на Mac.
Ну и ссылочки, чтобы было более понятно:
- https://neutralino.js.org/ — Сайт проекта
- https://neutralino.js.org/docs/ — Документация к JS API
- https://github.com/neutralinojs/neutralinojs — Репозиторий на GitHub
- https://github.com/neutralinojs/evaluation — Сравнение Hello World с конкурентами от разработчиков
- Neutralinojs 2019?—?Roadmap — Официальный план доработок
axifive
Предлагаю КДПВ:
PaulMaly
> Мы тащим только прослойку между каким-то браузером и какой-то ОС
Мне кажется одна лишь эта фраза сразу говорит нам, что подводных камней там полно.
maslyaev
Да уж, если «какой-то браузер» ещё не очень пугает (м.б. зря), то «какая-то ОС» — совсем беда. По-хорошему, нужно сделать единообразную прослойку ко всем функциям каждой ОС.
Так себе и представил ситуацию: ваяем на Нейтралино систему, вгрохали десяток человеколет, остаётся маленький штрих, без которого Заказчик не принимает — чтобы эта штука задействовала КриптоПро через виндовозный CryptoAPI. Плюс позарез оказалось нужно взаимодействовать с железячкой, для которой есть DLLка.
Впрочем, если сделают возможность приделывать к серверу написанные на плюсах плагины, то можно будет и выкрутиться.
bano-notit Автор
> если сделают возможность приделывать к серверу написанные на плюсах плагины, то можно будет и выкрутиться.
Проблема в том, что под каждую ОС свой сервер. А если вы делаете под одну ОС, то возникает вопрос почему не делаете нативно, раз умеете писать на плюсах плагины)
maslyaev
Предположим, затея взлетела, и писать кроссплатформенные штуки на этой штуке оказалось фантастически удобно. Сваяли большую красивую штуку, и тут это гадское КриптоПро. Делаем по-быстрому шлюз на CryptoAPI, и для Виндовса кнопка подписания электронной подписью появляется. А на других платформах она, допустим, и не нужна.
В общем объёме кодовой базы проекта этот шлюз порядка одного процента.
А нативно на плюсах, допустим, этот проект тоже можно было бы делать, но за на порядок больший бюджет, которого у Заказчика точно нет.
CoolCmd
может проще будет использовать Chromium Embedded Framework?
eugene_bb
Сделайте инсталятор который проверит и если надо установит гарантированную версию браузера. И проблем а с «каким-то браузером» решена.
Реализуйте версию «Neutralino сервер» на Node.js и загрузите гарантированную версию Node.js и проблема «какой-то ОС» решена.
И цикл замкнулся.
Кстати интересно, если ли «тонкий» Electron, т.е. node.js работает на удалённом сервере и всё крутится на нём, используется его файловая система, память и т.п., а ты только через браузер смотришь на результат. Или сетевые задержки слишком большие для UI?
nbytes
Веб называется. Нет ну серьезно, а зачем? То что вы описали по сути обычное веб-приложение.
На счёт сетевых задержек, есть такой сервис playkey, он позволяет играть в игры на облаке, я так понимаю, передавая в браузер видео достаточно хорошего качества и принимая события с устройств ввода и вроде ок. Так же на хабре была статья как пробросить иксы в браузер(Вот тут не скажу на сколько оно лагучее).
eugene_bb
Есть существующее Electron приложение и с минимальными изменениями конфигурации, делаем «тонкий» клиент.
Например одна из причин — более безопасное окружение с точки зрения эксплуатации, даже при скомпроментированных устройствах клиента, нету доступа до сырых данных.
bentall
Годная штука. Меня (как пользователя слаки) электрон отталкивает именно что своей жуткой неюниксвейностью. Очень надеюсь, что и во всякой убунте на правах пакета эта штука тоже приживётся со временем (и несколько тяжеловесное название этому не помешает).
Отсутствие прибитости к хрому тоже скорее в плюс, чем в минус, я может быть старомоден, но написание больших десктопных приложений привязанных к особенностям одного, пусть и самого распространённого броузера по мне — некомильфо. Как то напоминает времена виндовых приложений с использованием MSHTML engine (хотя опенсорсный fb2editor в wine таки запустить можно).
А так — если уж используешь фронтэндерскую технологию — будь добр писать мало-мальски кроссброузерный код, чтобы это можно и в веб выложить, без баннера «сайт доступен только для
IE6Chrome».Ладно, Atom и VSCode — это уже «реальность данная нам в ощущениях» (хотя я предпочитаю Sublime и, в качестве открытого аналога, TextAdept, полностью переконфигурируемый на lua). Но основное применение js-на-десктопе, как мне представляется, всё же должно быть иным.
ivan386
Больше похоже на HTML Application.
bentall
Да, вы правы. В том смысле, что HTA — это как раз пример того, какую роль десктопный JS должен играть. И Neutralinojs выглядит хорошим, годным кроссплатформенным HTA. Однако Electon выглядит чем-то куда боле монструозным.
В каком Windows? В новых виндах вроде будет клон хромиума в качестве браузера (хотя я то лично окончательно ушёл на Linux ещё в сравнительно благословенные времена Windows 7, сужу по новостям) и мне их Edge (который вроде бы пришёл на смену потомкам IE8) даже как-то жаль (во всяком случае исходники ChakraCore выглядят симпатично).
А так — ухищрения, как по мне, не чрезмерные. HTA? Да — HTA, при том, что броузер (как в общем-то для кроссплатформенного HTA логично) будет зависеть от конкретной версии конкретной ОСи. Ну так пишущий на HTML+JS как-то обязан уметь в кроссброузерность. Иначе лучше взять что-то другое, от Tcl/Tk до Qt (ну и .Net со временем обещает слиться, ага, в экстазе, c Mono и стоть по настоящему кроссплатформенным).
PS. Мне когда-то идея мозилловского XUL-а нравилась, но увы и ах — всё закончилось тем, что сама Mozilla выбросила эту технологию на помойку, и кто и как будет её поддерживать (и будет ли вообще) — сильно не ясно. ActiveState с их Komodo IDE вроде и не пытаются мозилловское ядро актуализировать, превращаясь в лютое legacy (как и Zotero), волчата из MoonChild серьёзным игроком не выглядят… Потому HTA — да, но привязка к любому конкретному броузерному движку — зло.
vitaliy2
axifive
Так, как раз было, в Chrome с поддержкой Chrome App, но Гугл, к сожалению, по непонятным причинам свернул этот функционал.
rPman
нет вы серьезно? HTTP протокол не делает различий между веб-клиентами! Тем более если ожидается что вебклиентом будет стандартный браузер! Какими механизмами этот всемогущий сервер, дающий доступ ко всему и вся от имени текущего пользователя, будет защищать компьютер от злонамеренных веб-приложений, запущенных в соседней вкладке?
Дополнительные механизмы авторизации? Усложнение механизмов установки приложения (токен авторизации выдается в этот момент) и прочее? Какой-нибудь нестандартный механизм, отличный от уже существующих систем установки приложений на компьютер (linux) Т.е. через некоторое время установка приложений превратится в очередной виндовый да да разрешить принять согласиться некст некст…