【问题标题】:child_process methods are slow on Electronchild_process 方法在 Electron 上很慢
【发布时间】:2019-09-17 04:37:47
【问题描述】:

我在 macOS 上使用 electron-packager 构建了一个 Electron 应用程序。在最简单的形式中,该应用程序由一个按钮组成,按下该按钮即可打开一个外部程序。

child_process.execFile('open', ['-a', 'Terminal', path])

与从终端运行应用程序相比,运行与终端分离的应用程序(例如使用 Spotlight 启动)时,我观察到上述函数调用的速度降低了 50 倍

hello.app/Contents/MacOS/hello

从终端启动 + 按下按钮 => 外部应用在 100 毫秒内打开

从 Spotlight 开始 + 按下按钮 => 外部应用在 5 秒内打开

任何提示可能是什么问题?

| Package           | Version  | 
| ----------------- | -------- |
| npm               | 6.4.1    |
| node              | v10.15.2 |
| electron          | 4.1.4    |
| electron-packager | 13.1.1   |

编辑:electron 6.0.9 和 electron-packager 14.0.5 的问题仍然存在

【问题讨论】:

  • 问题在 2020 年夏季仍然存在。任何更新都会很棒......

标签: node.js electron


【解决方案1】:

使用spawn 而不是execFile 可能会更好:这可能更合适,因为您正在运行open 命令,而不是直接执行特定文件(例如,启动应用程序) .

child_process.spawn('open', ['-a', 'Terminal', path]);

【讨论】:

  • 感谢您的建议。不幸的是,所有child_process 函数都有完全相同的问题(spawn、exec、execFile)。
【解决方案2】:

您可以使用spawn 来预热进程,在其中运行 bash 或其他终端,然后在其中键入命令。 我写了ShellService你可以看看。 在我的 Mac 上使用exec 执行正常打开命令大约需要 300 毫秒,但在 ShellService 中只需 1 毫秒。所以我认为时间都花在了创建一个新流程上。

export default class ShellService {
  // Use bash on mac and linux.
  // I don't know what to use for windows, temporarily write powershell.
  private shell = isWindows() ? spawn('powershell') : spawn('bash');
  constructor() {
    this.shell.addListener('exit', (code) => {
      console.error(`[shell] shell process exit with code:${code}`);
      if (!this.shell.stdin.writable) {
        this.shell = spawn('bash');
      }
    });
  }
  cmdQueue: string[] = [];
  isRunning = false;
  /**
   * run shell cmd in bash
   * @param cmd
   */
  public exeCmd(cmd: string) {
    this.cmdQueue.push(cmd);
    this.tryExeCmd();
  }
  private tryExeCmd() {
    if (this.isRunning || this.cmdQueue.length === 0) {
      return;
    }
    this.isRunning = true;
    const cmd = this.cmdQueue.shift();
    const startTime = new Date().getTime();
    // Timeout after one second
    const timeoutTimer = setTimeout(() => {
      this.isRunning = false;
      cubeReport({
        e: CubeEventId.ShellServiceTimeout,
        f: cmd,
      });
      console.warn(`Run cmd: ${cmd} timeout.`);
      this.shell.kill();
      this.shell = spawn('bash');
      this.tryExeCmd();
    }, 1000);
    this.shell.stdin.write(`${cmd}\n`, (err) => {
      this.isRunning = false;
      clearTimeout(timeoutTimer);
      console.log(`Run cmd: ${cmd} cost: ${new Date().getTime() - startTime}`);
      if (err) {
        console.error(`Run cmd: ${cmd} err: ${err}`);
      }
      this.tryExeCmd();
    });
  }
}

【讨论】:

    猜你喜欢
    • 2016-02-23
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2019-02-25
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    相关资源
    最近更新 更多