electron
  • 本文通过一个 Electron 应用示例对比了 MessageChannel 和 ipcRenderer.invoke/ipcMain.handle 两种 IPC 通信方式的性能差异。

1. 视频

2. demos.1 - MessageChannel vs. ipcRenderer.invoke、ipcMain.handle

  • 先说结论
    • 单向通信:两者差异不大
    • 双向通信:MessageChannel 的性能明显优于 ipcRenderer.invoke,MessageChannel 比 invoke 快了 3~5 倍。
      • 如果有短时间内多次在主进程和渲染进程之间互相通信的情况,可以优先考虑使用消息端口的方式来跑。
  • 该 demo 仅仅作为一个参考,实际需求往往会更加复杂,比如通信过程中会携带大量数据。本 demo 的测试用例比较简单,仅仅是传递一个写死的字符串。
index.jsjs
// 主进程
const { ipcMain, app, BrowserWindow, MessageChannelMain } = require('electron')

app.whenReady().then(() => {
  const win = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  })

  win.webContents.openDevTools()
  win.loadFile('./index.html')

  // #region 消息端口
  const { port1, port2 } = new MessageChannelMain()

  // 把其中一个端口丢给渲染进程
  win.once('ready-to-show', () =>
    win.webContents.postMessage('port', null, [port1]),
  )

  port2.on('message', ({ data }) => {
    console.count(`主进程收到了 message port 消息${data}`)
    port2.postMessage({ data: 'port2 response from main' })
  })
  // port2.start() 这一步别忘了,否则消息端口将无法正常接收消息。
  port2.start()
  // #endregion 消息端口

  // #region invoke、handle
  ipcMain.handle('invoke', async (event, message) => {
    console.count(`主进程收到了 invoke 消息${message}`)
    return 'invoke response from main'
  })
  // #endregion invoke、handle
})

Discussions

正在载入评论…