Electron 是一个框架,用于将基 于HTML5 / JavaScript 的应用程序打包到多个平台(Windows / MacOS / Linux)的独立桌面应用程序中。
Electron核心是拥有两个或多个并发运行的操作系统级进程:main和render进程。
在活动监视器里可以看到多少进程与该程序关联,Electron 是主进程,一个Electron Helper 是 GPU 进程,另几个是渲染进程。
这些进程每个都彼此同时运行,并且进程的内存和资源是相互隔离的。
为什么要多进程?
这个架构决策源自 Chromium。Chromium 在一个单独的进程中运行每个选项卡(即 webContents 实例),这样如果一个选项卡遇到致命错误,它就不会关闭整个应用程序。从这个意义上讲,“Chromium 就像操作系统一样构建,使用多个操作系统进程将网站彼此隔离并与浏览器本身隔离。”因此,每个进程“在自己的地址空间中运行,由操作系统调度,并且可以独立失败。当意外地编写了一个无限循环,然后关闭了它运行的选项卡,而不是整个浏览器。这种架构是为了感谢这种弹性。还有安全原因。
主进程
主要流程负责创建和管理 BrowserWindow 实例和各种应用程序事件。它还可以执行诸如注册全局快捷方式,创建本机菜单和对话框,响应自动更新事件等操作。您应用的入口点将指向将在主进程中执行的 JavaScript 文件。主进程中提供了Electron API的子集(请参见下图),以及所有node.js模块。
渲染进程
渲染过程负责运行应用程序的用户界面,也就是一个 web 页面,它是 webContents 的一个实例。渲染器中提供了所有 DOM API,node.js API 和 Electron API的子集(请参见下图)。
不要把 BrowserWindow 与渲染器进程混淆了,在窗口包含 webContents 实例之前,实际上不会创建渲染进程,单个窗口中可以有一个或多个 webContents,因为一个窗口里可以有多个 webview,每个 webview 都有自己的 webContents 实例和渲染器进程。
进程间通信
Electron 使用进程间通信(IPC)在进程之间进行通信。
利用remote 模块可以直接使用主进程模块,就像 Menu 在渲染器中可用一样,不需要手动 IPC 调用,但幕后真正发生的是你通过同步 IPC 调用向主进程发出命令。
使用 devtron 工具可以查看到使用 remote 远程模块时发生的所有IPC调用,同步IPC调用可能会有一些性能影响。
CPU密集型任务
不要在主进程中进行 CPU 密集型工作,它将锁定所有渲染器进程,可能会阻塞渲染进程的 UI。这些任务应该在一个单独的进程中运行,而不是具有 UI 的现有渲染器或者主进程中。
最简单的方法是使用 Electron-remote,它有一个渲染器进程任务池,可以跨多个进程拆分和平衡工作。
例子:
electron-remote-example.js
// This works in the either the main or renderer processes.
const { requireTaskPool } = require('electron-remote');
const work = requireTaskPool(require.resolve('./work'));
console.log('start work');
// `work` will get executed concurrently in separate processes
work().then(result => {
console.log('work done');
console.log(result);
});
work().then(result => {
console.log('work done');
console.log(result);
});
work().then(result => {
console.log('work done');
console.log(result);
});
work.js
const crypto = require('crypto');
// this usually takes a few seconds
function work(limit = 100000) {
let start = Date.now();
n = 0;
while(n < limit) {
crypto.randomBytes(2048);
n++;
}
return {
timeElapsed: Date.now() - start,
};
}
module.exports = work;
注:该项目 electron-remote 已弃用不再维护。