Electron - 一致的性能和启动子 Node.js 进程
Electron - consistent performance and spinning up a child Node.js process
在我给出一些背景之前,我想澄清一下,我不是在寻找如何在 Electron 运行time 下简单地生成一个新脚本作为渲染器进程,我正在尝试使用普通节点 运行time.
所以我知道 Electron 在其引擎盖下有一些与 NW.js 相似的 JS 运行time 的不同风格,我正在努力为我的报告获得一致的性能结果。
不幸的是,这似乎比我想象的要困难得多。我专门测试了 mailparser
模块的速度,尽管这在这里并不一定很重要。
我首先 运行 在我们使用的 Electron 应用程序上使用它,它使用 Electron Forge。我通过 IPC 调用了测试脚本,因为这是我们打算使用的,所以它是在 ipcMain.handle
的回调中调用的。在这里,性能非常糟糕,我们的测试需要 30-50 秒才能完成。
然后我 运行 一个测试脚本,它只在同一个 Electron Forge 应用程序中打开一个空白的 HTML 文件,并且 运行s 中的测试脚本背景。这在 8-12 秒时要好得多。
接下来,我设置了一个新目录,其中包含测试集、普通 Electron 安装和 mailparser
安装。我在这里没有 electron-rebuild
,但是 mailparser
确实依赖于 node-iconv
,所以有原生绑定。
我运行 一个测试脚本,Electron 只是调用同一行代码。这没有使用 Electron Forge。这里的表现稍微好一点,在 5-9 秒。
然后我运行另一个测试脚本,这次只有普通的旧节点,这里的性能在 1-3s 时非常好。
所以我这里有两个问题:
为什么 Electron 测试中的性能差异如此之大?虽然我用的是IPCMain,但是我用的是新的.handle
,应该是异步的,运行是在Electron的节点运行time的上下文中,所以应该和运行有一样的性能ning外回调。此外,Electron Forge 和普通 Electron 测试也有几秒钟的差异,这对我来说毫无意义,因为我认为 Electron Forge 只会将 Electron 二进制文件封装在引擎盖下。
寻求最佳和一致的结果,我想知道如何在 Electron 中使用节点 运行time 启动子进程。这样做通常只是启动一个新的渲染器进程,这是 运行ning Electron 的(较慢的)JS 运行time。我想避免离开 Electron Forge,但我能想到的唯一解决方案是将预编译的二进制文件与进程 运行ning 捆绑在为每个平台构建的节点 运行time 下。
对于问题 1,如果不能在代码中复制它,就很难知道问题出在哪里。您可以尝试为 Electron 团队发布一个 issue on the Github site 来解决这个问题。他们更有可能知道答案,但他们也要求提供代码。
话虽如此,启动一个仅是 运行ning 节点的子进程并使您免于 Electron/Electron Forge 开销并不难。最简单的是使用节点的 fork 命令,但告诉它使用主节点可执行文件而不是 electron.exe。你可以直接把脚本交给运行,这样你就不用担心预编译的二进制文件了。
下面的代码(和 here)运行ning 在主进程上将 运行 同一文件夹中名为 server.js 的脚本:
const serverPath = path.join(__dirname, 'server.js');
const { fork } = require('child_process');
child = fork(serverPath, [],
{
execPath: "node",
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
});
如果你这样做,你会得到一个启用了 IPC 的子 node.exe 进程,而不是 electron.exe 进程。它可以通过 IPC 与主 Electron 进程进行通信。它还可以使用从您常用的 package.json 安装的任何 npm 模块,因为该脚本可以与您的其他脚本位于同一文件夹中。因此,如果可行,这是一个非常干净的解决方案。
今天下午我通过编写一些执行此操作的代码来娱乐自己。 I’ve put this on Github. It uses mailparser to parse a simple mail in the node.exe process in server.js.
据我所知,就包含正确的脚本而言,这也与 Electron Forge 正确打包。它不会打包节点本身,因此要么需要安装在目标机器上,要么我认为您需要分发 node.exe.
顺便说一句,您是否真的尝试过这种方法并不完全清楚,它是 运行 速度缓慢的场景之一。仍然有一些开销,因为我们正在设置 IPC。如果它在您的用例中仍然 运行 缓慢,那么我认为可以使用节点的 spawn 命令来创建一个完全独立的进程。
在我给出一些背景之前,我想澄清一下,我不是在寻找如何在 Electron 运行time 下简单地生成一个新脚本作为渲染器进程,我正在尝试使用普通节点 运行time.
所以我知道 Electron 在其引擎盖下有一些与 NW.js 相似的 JS 运行time 的不同风格,我正在努力为我的报告获得一致的性能结果。
不幸的是,这似乎比我想象的要困难得多。我专门测试了 mailparser
模块的速度,尽管这在这里并不一定很重要。
我首先 运行 在我们使用的 Electron 应用程序上使用它,它使用 Electron Forge。我通过 IPC 调用了测试脚本,因为这是我们打算使用的,所以它是在
ipcMain.handle
的回调中调用的。在这里,性能非常糟糕,我们的测试需要 30-50 秒才能完成。然后我 运行 一个测试脚本,它只在同一个 Electron Forge 应用程序中打开一个空白的 HTML 文件,并且 运行s 中的测试脚本背景。这在 8-12 秒时要好得多。
接下来,我设置了一个新目录,其中包含测试集、普通 Electron 安装和 mailparser
安装。我在这里没有 electron-rebuild
,但是 mailparser
确实依赖于 node-iconv
,所以有原生绑定。
我运行 一个测试脚本,Electron 只是调用同一行代码。这没有使用 Electron Forge。这里的表现稍微好一点,在 5-9 秒。
然后我运行另一个测试脚本,这次只有普通的旧节点,这里的性能在 1-3s 时非常好。
所以我这里有两个问题:
为什么 Electron 测试中的性能差异如此之大?虽然我用的是IPCMain,但是我用的是新的
.handle
,应该是异步的,运行是在Electron的节点运行time的上下文中,所以应该和运行有一样的性能ning外回调。此外,Electron Forge 和普通 Electron 测试也有几秒钟的差异,这对我来说毫无意义,因为我认为 Electron Forge 只会将 Electron 二进制文件封装在引擎盖下。寻求最佳和一致的结果,我想知道如何在 Electron 中使用节点 运行time 启动子进程。这样做通常只是启动一个新的渲染器进程,这是 运行ning Electron 的(较慢的)JS 运行time。我想避免离开 Electron Forge,但我能想到的唯一解决方案是将预编译的二进制文件与进程 运行ning 捆绑在为每个平台构建的节点 运行time 下。
对于问题 1,如果不能在代码中复制它,就很难知道问题出在哪里。您可以尝试为 Electron 团队发布一个 issue on the Github site 来解决这个问题。他们更有可能知道答案,但他们也要求提供代码。
话虽如此,启动一个仅是 运行ning 节点的子进程并使您免于 Electron/Electron Forge 开销并不难。最简单的是使用节点的 fork 命令,但告诉它使用主节点可执行文件而不是 electron.exe。你可以直接把脚本交给运行,这样你就不用担心预编译的二进制文件了。
下面的代码(和 here)运行ning 在主进程上将 运行 同一文件夹中名为 server.js 的脚本:
const serverPath = path.join(__dirname, 'server.js');
const { fork } = require('child_process');
child = fork(serverPath, [],
{
execPath: "node",
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
});
如果你这样做,你会得到一个启用了 IPC 的子 node.exe 进程,而不是 electron.exe 进程。它可以通过 IPC 与主 Electron 进程进行通信。它还可以使用从您常用的 package.json 安装的任何 npm 模块,因为该脚本可以与您的其他脚本位于同一文件夹中。因此,如果可行,这是一个非常干净的解决方案。
今天下午我通过编写一些执行此操作的代码来娱乐自己。 I’ve put this on Github. It uses mailparser to parse a simple mail in the node.exe process in server.js.
据我所知,就包含正确的脚本而言,这也与 Electron Forge 正确打包。它不会打包节点本身,因此要么需要安装在目标机器上,要么我认为您需要分发 node.exe.
顺便说一句,您是否真的尝试过这种方法并不完全清楚,它是 运行 速度缓慢的场景之一。仍然有一些开销,因为我们正在设置 IPC。如果它在您的用例中仍然 运行 缓慢,那么我认为可以使用节点的 spawn 命令来创建一个完全独立的进程。