Electron团队提供remote模块给开发者,
主要目的是为了简化渲染进程和主进程互访的难度,
这个目的却是达到了。
但也带来了很多问题,
归纳起来主要分为以下四点:
第一:它很慢
通过remote模块可以访问主进程的对象、类型、方法,
但这些操作都是跨进程的,
跨进程操作性能上的损耗可能是进程内操作的几百倍甚至上千倍。
假设你在渲染进程通过remote模块创建了一个BrowserWindow对象,
不但你创建这个对象的过程很慢,
后面你使用这个对象的过程也很慢。
小到更新这个对象的属性,
大到使用这个对象的方法,
都是跨进程的,
这种累积性的性能损耗,
可想而知影响有多大。
第二:它会制造混乱
假设我们在渲染进程中通过remote模块使用了主进程的某个对象,
此对象在某个时刻会触发一个事件(BrowserWindow对象中就有很多这样的事件),
事件处理程序是在渲染进程中注册的,
当事件发生时,实际上是主进程的原始对象先接到这个事件,
再异步的通知渲染进程要执行事件处理程序,
此时可能已经错过了很多事情,
类似event.preventDefault()这样的操作可能毫无意义。
在一个业务复杂的应用中这类错误非常难排查。
第三:它会制造假象
我们在渲染进程中通过remote模块使用了主进程的某个对象,
得到的是这个对象的映射,是一个代理对象,
它看起来像是真正的对象,但实际上不是。
首先这个对象原型链上的属性不会被映射到渲染进程的代理对象上。
其次类似NaN、Infinity这样的值不会被正确的映射给渲染进程,
如果一个主进程方法返回一个NaN值
那么渲染进程通过remote模块访问这个方法将会得到undefined。
第四:它存在安全问题
因为remote模块底层还是通过IPC管道与主进程通信的,
那么假设你的应用需要加载第三方网页,
即使你让这些网页运行在安全沙箱内,
恶意代码仍可能通过原型污染攻击来模拟remote模块的远程消息
以获取访问主进程模块的权力,逃离沙箱的控制。
反思
remote模块并非一无是处
Electron进程间通讯确实非常复杂,
不但增加了开发人员的劳动,还增加了开发人员的心智负担
没有remote模块开发人员该怎么办呢
要么就实现自己的进程间通信工具(我就做过一个跨进程的消息总线)
要么就强行引入remote模块
实际上remote模块并非被干掉了
而是从核心模块变成了可供开发者选择的模块
决策权交给了开发者
但开发者再使用remote模块时,一定要考虑上面提到的那四个问题
不然你的应用程序可能会存在不稳定的现象。