Electron团队为什么要干掉remote模块

Electron的remote模块虽然简化了渲染进程与主进程的交互,但因其慢速、混乱、假象和安全问题,团队面临挑战。远程操作性能损耗严重,事件处理混乱,对象映射不完整,且存在安全风险。开发者需谨慎考虑这些问题,可以考虑自定义进程间通信解决方案或使用已不再核心的remote模块。

Electron团队提供remote模块给开发者,

主要目的是为了简化渲染进程和主进程互访的难度,

这个目的却是达到了。

但也带来了很多问题,

归纳起来主要分为以下四点:

第一:它很慢

通过remote模块可以访问主进程的对象、类型、方法,

但这些操作都是跨进程的,

跨进程操作性能上的损耗可能是进程内操作的几百倍甚至上千倍。

假设你在渲染进程通过remote模块创建了一个BrowserWindow对象,

不但你创建这个对象的过程很慢,

后面你使用这个对象的过程也很慢。

小到更新这个对象的属性,

大到使用这个对象的方法,

都是跨进程的,

这种累积性的性能损耗,

可想而知影响有多大。


第二:它会制造混乱

假设我们在渲染进程中通过remote模块使用了主进程的某个对象,

此对象在某个时刻会触发一个事件(BrowserWindow对象中就有很多这样的事件),

事件处理程序是在渲染进程中注册的,

当事件发生时,实际上是主进程的原始对象先接到这个事件,

再异步的通知渲染进程要执行事件处理程序,

此时可能已经错过了很多事情,

类似event.preventDefault()这样的操作可能毫无意义。

在一个业务复杂的应用中这类错误非常难排查。


第三:它会制造假象

我们在渲染进程中通过remote模块使用了主进程的某个对象,

得到的是这个对象的映射,是一个代理对象,

它看起来像是真正的对象,但实际上不是。

首先这个对象原型链上的属性不会被映射到渲染进程的代理对象上。

其次类似NaN、Infinity这样的值不会被正确的映射给渲染进程,

如果一个主进程方法返回一个NaN值

那么渲染进程通过remote模块访问这个方法将会得到undefined。

第四:它存在安全问题

因为remote模块底层还是通过IPC管道与主进程通信的,

那么假设你的应用需要加载第三方网页,

即使你让这些网页运行在安全沙箱内,

恶意代码仍可能通过原型污染攻击来模拟remote模块的远程消息

以获取访问主进程模块的权力,逃离沙箱的控制。

反思

remote模块并非一无是处

Electron进程间通讯确实非常复杂,

不但增加了开发人员的劳动,还增加了开发人员的心智负担

没有remote模块开发人员该怎么办呢

要么就实现自己的进程间通信工具(我就做过一个跨进程的消息总线)

要么就强行引入remote模块

实际上remote模块并非被干掉了

而是从核心模块变成了可供开发者选择的模块

决策权交给了开发者

但开发者再使用remote模块时,一定要考虑上面提到的那四个问题

不然你的应用程序可能会存在不稳定的现象。

欢迎加QQ群:949674481一起探讨

 

 

 

在React项目中使用Electron的`ipc`模块,不一定需要使用`remote`模块。你可以在渲染进程中直接使用`ipcRenderer`模块,而在主进程中使用`ipcMain`模块。以下是示例代码: 在Electron的主进程中: ```javascript const { ipcMain, BrowserWindow } = require('electron'); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }); mainWindow.loadFile('index.html'); mainWindow.on('closed', () => { mainWindow = null; }); } ipcMain.on('message-from-renderer', (event, arg) => { console.log(arg); // 输出来自渲染进程的消息 event.reply('message-from-main', 'Hello from main process!'); // 发送回复消息到渲染进程 }); createWindow(); ``` 在React组件中: ```javascript import React, { useState, useEffect } from 'react'; import { ipcRenderer } from 'electron'; function MyComponent() { const [message, setMessage] = useState(''); useEffect(() => { const handleMainResponse = (event, arg) => { setMessage(arg); // 接收来自主进程的消息 }; ipcRenderer.on('message-from-main', handleMainResponse); return () => { ipcRenderer.removeListener('message-from-main', handleMainResponse); // 移除事件监听器 }; }, []); const handleClick = () => { ipcRenderer.send('message-from-renderer', 'Hello from renderer process!'); // 发送消息到主进程 }; return ( <div> <button onClick={handleClick}>发送消息到主进程</button> {message && <p>收到来自主进程的消息:{message}</p>} </div> ); } ``` 注意,在使用`ipcMain`模块时,要在主进程中使用`webPreferences.nodeIntegration`选项来启用Node.js集成,以便在主进程中使用Node.js模块。而在渲染进程中,不需要使用`webPreferences.nodeIntegration`选项,因为默认情况下React项目已经启用了Node.js集成。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liulun

如果文章真帮到了你,谢谢您打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值