javascript - 为什么 Electron 为每个窗口生成一个进程?

标签 javascript typescript electron

我正在开发具有多个窗口的 Electron 应用程序。假设我有一个主窗口和几个子窗口。

如果我从主进程中打开 google.com 创建 20 个子窗口,它会产生大约 23 个 Electron 进程(每个窗口一个 + GPU 进程 + 其他进程)并在我的 Windows 10 机器上总共消耗大约 800 MB 的内存.这显然很多。

const {app, BrowserWindow} = require('electron')

let mainWindow

const webPreferences = {
  sandbox: true
};

function createWindow () {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences
  })

  mainWindow.loadFile('index.html')

  for (var t = 0; t < 20; t++) {
    const childWindow = new BrowserWindow({
      webPreferences
    })

    childWindow.loadURL('https://google.com')
  }
}

app.on('ready', createWindow)

Task Manager with 23 Electron processes

我知道这就是 Chromium 的工作方式 - 每个选项卡都是一个单独的进程,所以如果一个选项卡坏了,整个浏览器和其他选项卡都还活着。我对此毫不怀疑,但我注意到一件有趣的事情。如果我按照 here 所述使用 native window.open它神秘地只产生 4 个进程。它以某种方式将所有“窗口”进程组合成一个进程 + GPU + 总共消耗 400 MB 的其他东西,这是更好的结果。

const {app, BrowserWindow} = require('electron')

let mainWindow

const webPreferences = {
  sandbox: true // without sandboxing it spawns 23 processes again :(
};

function createWindow () {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences
  })

  mainWindow.loadFile('index.html')

  mainWindow.webContents.on('new-window', (event, url, frameName, disposition, options) => {
    event.preventDefault()
    const win = new BrowserWindow({
      ...options,
      show: false,
      webPreferences
    })
    win.once('ready-to-show', () => win.show())
    if (!options.webContents) {
      win.loadURL(url) // existing webContents will be navigated automatically
    }
    event.newGuest = win
  })
}

app.on('ready', createWindow)

和index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    <script>
        for (var t = 0; t < 20; t++) {
            window.open('https://google.com');
        }
    </script>
  </body>
</html>

Task Manager with 4 Electron processes

如果我从主进程(第一个片段)创建它们,是否有任何方法可以让所有子窗口只有一个进程?如果有人能解释为什么它以这种方式工作,那就太好了。

附言我在 Electron 6.0.2 运行时使用 electron fiddler 来运行这些片段

最佳答案

更新:正在删除亲和性,请参阅 https://github.com/electron/electron/pull/26874 .

affinity 选项可以解决问题。具有相同亲缘关系的窗口将聚集在一个进程中。

可以在此处找到有关此功能的更多详细信息

https://github.com/electron/electron/pull/11501

这里

https://electronjs.org/docs/api/browser-window#new-browserwindowoptions

关于javascript - 为什么 Electron 为每个窗口生成一个进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57528101/

相关文章:

javascript - 如何在 Javascript 中跳出循环并停止计数器变量?

javascript - 有没有办法防止来自机器人的点击输入?

angular - 如何根据角色启用组件/操作?

windows - 如何检测 Electron/ Chrome 应用程序中的 Windows 软键盘?

javascript - 迁移到 V5 后序列化记录问号而不是值

php - 拖放 Div 删除

node.js - 无法在 Electron 项目中通过 yarn 安装包(Python 语法错误?)

database - 将 Electron 与数据库文件一起使用

javascript - Stripe Angular Controller 不更新 View

node.js - 如何在不将目标设置为 ES6 的情况下获得 typescript 中生成器的支持?