Electron - стабильная производительность и ускорение дочернего процесса Node.js

Прежде чем я расскажу немного о себе, я хотел бы уточнить, что я не ищу, как просто создать новый скрипт в среде выполнения Electron в качестве процесса рендеринга, я пытаюсь использовать простую среду выполнения Node.

Итак, я знаю, что у Electron есть другая разновидность среды выполнения JS, похожая на NW.js, и я пытаюсь получить согласованные результаты производительности для своего отчета.

К сожалению, это оказалось намного сложнее, чем я предполагал. Я специально тестирую скорость модуля mailparser, хотя здесь это не обязательно важно.

  1. Сначала я запустил его в приложении Electron, с которым мы работаем, которое использует Electron Forge. Я вызвал тестовый сценарий через IPC, так как мы собираемся его использовать, поэтому он был вызван в обратном вызове для ipcMain.handle. Здесь производительность была действительно плохой, и для завершения нашего теста требовалось 30-50 секунд.

  2. Затем я запустил тестовый скрипт, который просто открывает пустой HTML-файл в том же приложении Electron Forge и запускает тестовый скрипт в фоновом режиме. Это было намного лучше на 8-12 секундах.

Затем я создал новый каталог с тестовым набором, простой установкой Electron и установкой mailparser. Я не electron-rebuild здесь, но mailparser полагается на node-iconv и поэтому имеет собственные привязки.

  1. Я запустил тестовый сценарий, в котором Electron просто вызвал ту же строку кода. Это не использовало Electron Forge. Производительность здесь была немного лучше - 5-9 секунд.

  2. Затем я запустил еще один тестовый сценарий, на этот раз только с обычным старым узлом, и производительность здесь была отличной на 1-3 с.

Итак, у меня есть два вопроса:

  1. Почему производительность в тестах Electron так сильно различается? Хотя я использовал IPCMain, я использовал новый .handle, который должен быть асинхронным и запускаться в контексте среды выполнения узла Electron, поэтому он должен иметь такую ​​же производительность, как и работа вне обратного вызова. Более того, тесты Electron Forge и обычные тесты Electron также различаются на пару секунд, что для меня не имело смысла, поскольку я предполагал, что Electron Forge просто закроет двоичную систему Electron под капотом.

  2. В поисках оптимальных и последовательных результатов мне интересно, как я могу развернуть дочерний процесс со средой выполнения узла внутри Electron. Обычно это просто запускает новый процесс рендеринга, который запускает (более медленную) среду выполнения JS Electron. Я бы не хотел покидать Electron Forge, но единственное решение, которое я могу придумать, - это связать предварительно скомпилированные двоичные файлы с процессом, работающим в среде выполнения Node, созданной для каждой платформы.


person Priansh Shah    schedule 13.08.2020    source источник


Ответы (1)


Что касается вопроса 1, трудно понять, в чем проблема, не имея возможности воспроизвести ее в коде. Вы можете попробовать опубликовать проблему на сайте Github для команды Electron по этому поводу. Они с большей вероятностью знают ответ, но они также просят код.

Сказав это, нетрудно развернуть дочерний процесс, который просто выполняет node и освобождает вас от накладных расходов Electron / Electron Forge. Самый простой - использовать команду узла fork, но указать ей использовать основной узел исполняемый файл, а не Electron.exe. Вы можете просто передать ему сценарий для запуска, так что вам не нужно беспокоиться о предварительно скомпилированных двоичных файлах.

Код ниже (и здесь), запущенный в основном процессе, запустит сценарий с именем server.js в той же папке:

    const serverPath = path.join(__dirname, 'server.js');
    const { fork } = require('child_process');
    child = fork(serverPath, [],
        {
            execPath: "node",
            stdio: ['pipe', 'pipe', 'pipe', 'ipc']
        });

Если вы это сделаете, вы получите дочерний процесс node.exe с включенным IPC, а не процесс Electron.exe. Его можно заставить общаться через IPC с основным процессом Electron. Он также может использовать любые модули npm, установленные из вашего обычного package.json, потому что сценарий может находиться в той же папке, что и другие ваши сценарии. Так что, если это сработает, это довольно чистое решение.

Сегодня днем ​​я развлекался написанием кода, который делает это. Я разместил это на Github. Он использует mailparser для анализа простого письма в процессе node.exe в server.js.

Насколько я могу судить, это также правильно упаковано с Electron Forge с точки зрения включения правильных скриптов. Он не будет упаковывать сам узел, поэтому либо его нужно установить на целевой машине, либо, я думаю, вам нужно будет распространить node.exe.

Между прочим, не совсем понятно, пробовали ли вы этот подход на самом деле, и это один из тех сценариев, где он работает медленно. По-прежнему есть некоторые накладные расходы, потому что мы настраиваем IPC. Если в вашем варианте использования он по-прежнему работает медленно, я думаю, что можно использовать команду spawn узла для создания полностью автономного процесса.

person Rich N    schedule 24.11.2020