Недавно я совершенно случайно наткнулся на простую рекламную заметочку "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.


Ну и ссылочки, чтобы было более понятно:


Комментарии (15)


  1. axifive
    01.02.2019 18:44

    Предлагаю КДПВ:

    Спойлер
    image


  1. PaulMaly
    01.02.2019 19:24

    > Мы тащим только прослойку между каким-то браузером и какой-то ОС

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


    1. maslyaev
      01.02.2019 19:55

      Да уж, если «какой-то браузер» ещё не очень пугает (м.б. зря), то «какая-то ОС» — совсем беда. По-хорошему, нужно сделать единообразную прослойку ко всем функциям каждой ОС.

      Так себе и представил ситуацию: ваяем на Нейтралино систему, вгрохали десяток человеколет, остаётся маленький штрих, без которого Заказчик не принимает — чтобы эта штука задействовала КриптоПро через виндовозный CryptoAPI. Плюс позарез оказалось нужно взаимодействовать с железячкой, для которой есть DLLка.

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


      1. bano-notit Автор
        01.02.2019 20:10

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

        Проблема в том, что под каждую ОС свой сервер. А если вы делаете под одну ОС, то возникает вопрос почему не делаете нативно, раз умеете писать на плюсах плагины)


        1. maslyaev
          01.02.2019 21:34

          Предположим, затея взлетела, и писать кроссплатформенные штуки на этой штуке оказалось фантастически удобно. Сваяли большую красивую штуку, и тут это гадское КриптоПро. Делаем по-быстрому шлюз на CryptoAPI, и для Виндовса кнопка подписания электронной подписью появляется. А на других платформах она, допустим, и не нужна.
          В общем объёме кодовой базы проекта этот шлюз порядка одного процента.
          А нативно на плюсах, допустим, этот проект тоже можно было бы делать, но за на порядок больший бюджет, которого у Заказчика точно нет.


      1. CoolCmd
        02.02.2019 00:05

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

        может проще будет использовать Chromium Embedded Framework?


  1. eugene_bb
    01.02.2019 19:39

    Сделайте инсталятор который проверит и если надо установит гарантированную версию браузера. И проблем а с «каким-то браузером» решена.

    Реализуйте версию «Neutralino сервер» на Node.js и загрузите гарантированную версию Node.js и проблема «какой-то ОС» решена.

    И цикл замкнулся.

    Кстати интересно, если ли «тонкий» Electron, т.е. node.js работает на удалённом сервере и всё крутится на нём, используется его файловая система, память и т.п., а ты только через браузер смотришь на результат. Или сетевые задержки слишком большие для UI?


    1. nbytes
      01.02.2019 20:58

      т.е. node.js работает на удалённом сервере и всё крутится на нём, используется его файловая система, память и т.п., а ты только через браузер смотришь на результат.

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


      1. eugene_bb
        01.02.2019 21:18

        Нет ну серьезно, а зачем?
        «Потому что может»

        Есть существующее Electron приложение и с минимальными изменениями конфигурации, делаем «тонкий» клиент.

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


  1. bentall
    01.02.2019 23:27

    Годная штука. Меня (как пользователя слаки) электрон отталкивает именно что своей жуткой неюниксвейностью. Очень надеюсь, что и во всякой убунте на правах пакета эта штука тоже приживётся со временем (и несколько тяжеловесное название этому не помешает).

    Отсутствие прибитости к хрому тоже скорее в плюс, чем в минус, я может быть старомоден, но написание больших десктопных приложений привязанных к особенностям одного, пусть и самого распространённого броузера по мне — некомильфо. Как то напоминает времена виндовых приложений с использованием MSHTML engine (хотя опенсорсный fb2editor в wine таки запустить можно).

    А так — если уж используешь фронтэндерскую технологию — будь добр писать мало-мальски кроссброузерный код, чтобы это можно и в веб выложить, без баннера «сайт доступен только для IE6 Chrome».

    Ладно, Atom и VSCode — это уже «реальность данная нам в ощущениях» (хотя я предпочитаю Sublime и, в качестве открытого аналога, TextAdept, полностью переконфигурируемый на lua). Но основное применение js-на-десктопе, как мне представляется, всё же должно быть иным.


    1. ivan386
      02.02.2019 00:13
      +1

      Больше похоже на HTML Application.


      То есть мы возвращаемся в лехие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows.


      1. bentall
        02.02.2019 02:25

        Да, вы правы. В том смысле, что HTA — это как раз пример того, какую роль десктопный JS должен играть. И Neutralinojs выглядит хорошим, годным кроссплатформенным HTA. Однако Electon выглядит чем-то куда боле монструозным.

        мы возвращаемся в лихие нулевые и ухищряемся всеми возможными способами, чтобы попасть в тот самый IE 8, который будет стандартным WebView на Windows


        В каком 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 — да, но привязка к любому конкретному броузерному движку — зло.


  1. vitaliy2
    02.02.2019 11:55
    +1

    1. По поводу памяти — так и не понял, почему должно есть меньше памяти. Ведь браузер или webview или что-то ещё всё-таки запускаются. Единственное, что не запускается — node.js, но тут как раз и минус — теряем стандартные API. Может быть фишка в том, что мы открываем как бы новую вкладку, а не браузер целиком, не тратя память на UI браузера и прочие плюшки? Если да, то Electron не доработан, т.?к. это всё должно быть вырезано из браузера для экономии (что впрочем пока не отменяет преимущества Neutralino.js).
    2. Почему бы вместо стандартного браузера не сделать поиск браузеров и выбрать самый лучший? Поиск — очень быстрая операция, долстаточно проверить папки Program files, Program files (x86), AppData/Local и ветку реестра с установленными программами. Вложенные ветки или папки проверять не нужно. После поиска браузера сохранить результат, чтобы второй раз искать не пришлось. Также дать возможность пользователю изменить выбор. А автор приложения просто напишет что-то типа «Требования: установленный Google Chrome версии 62 и более».
    3. Возможно, те задачи, которые решает Neutralino.js, мог бы решать GraalVM (полностью совместимый аналог node.js) + GTK+ либо node.js + GTK+, юзая биндинги. При этом сохранился бы нодовский API, а пользователь бы получил приложение с действительно нативным интерфейсом, занимающее мало места и мало памяти (в несколько раз меньше, чем самое простое приложение на Electron).


    1. axifive
      02.02.2019 14:13

      Может быть фишка в том, что мы открываем как бы новую вкладку, а не браузер целиком, не тратя память на UI браузера и прочие плюшки?

      Так, как раз было, в Chrome с поддержкой Chrome App, но Гугл, к сожалению, по непонятным причинам свернул этот функционал.


  1. rPman
    02.02.2019 23:54

    Сервер запускается сразу и является настоящим партизаном в тылу ОС. Он умеет хранить данные, открывать файлы, писать в файлы, запускать крипторы shell-команды. Собственно он делает всё, что может понадобиться, предоставляет API для операционки и общается с помощью HTTP с клиентом. Так же он отдаёт клиенту всё, что тот должен отобразить на экране. Достаточно стандартная функциональность для сервера.
    А?!
    нет вы серьезно? HTTP протокол не делает различий между веб-клиентами! Тем более если ожидается что вебклиентом будет стандартный браузер! Какими механизмами этот всемогущий сервер, дающий доступ ко всему и вся от имени текущего пользователя, будет защищать компьютер от злонамеренных веб-приложений, запущенных в соседней вкладке?

    Дополнительные механизмы авторизации? Усложнение механизмов установки приложения (токен авторизации выдается в этот момент) и прочее? Какой-нибудь нестандартный механизм, отличный от уже существующих систем установки приложений на компьютер (linux) Т.е. через некоторое время установка приложений превратится в очередной виндовый да да разрешить принять согласиться некст некст…