Electron 团队为什么要干掉 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 一起探讨
评论