electron
首发于electron
史上最小的mini-electron发布了

史上最小的mini-electron发布了

还在为electron太庞大发愁吗


weolar.github.io/minibl


electron是目前最流行的跨平台PC开发框架,相当于把nodejs和chromium结合起来,可以同时使用两者的功能。

Miniblink:极致小巧的H5内核weolar.github.io/minibl

(如果不想看废话,需要了解怎么使用的人,可以拉到文末。另只支持windows系统)

但electron有个天生的缺点,由于使用了nodejs+chromium,所以体积庞大无比,内存占用高居不下。

随便一个应用,需要这么多文件


很显然,chromium里的绝大部分东西,对绝大部分人是没任何用的。比如你写一个小剪切板管理程序,肯定不会用到pdf预览、天城文或阿拉伯文支持、webrtc通信、多进程、ffmpeg视频展示等…

所以肯定很多需要一个仅保留基本网页渲染能力+调用nodejs功能的精简版electron。

mini-electron正是为此而生。


nodejs使用了v8,而miniblink因为本身就是chromium的blink+v8。关于miniblink的介绍,可以见官网


https://weolar.github.io/miniblinkweolar.github.io

极致小巧的浏览器内核

所以某天我大胆的猜测,miniblink只要加上nodejs的功能,再补上electron为了撮合这几个部件的胶水代码,就可以实现超级精简的electron了。


事实证明这样完全没问题,mini-eletcron目前已实现原版electron大约90%的接口。绝大部分electron app已能跑起。


mini-eletcron的实现方式很简单,由两部分组成:


1,mini-eletcron.exe;


2,nodejs.dll;


先看mini-electron.exe部分。这是个只有几百K的小exe(原版的electron.exe有大约5-60m)。其目的是调用nodejs.dll导出的接口,以模拟electron的功能。由于原版electron是开源的,所以我直接挪用了很多代码。当然,需要做大量改动。原因有二:一是因为原版代码大量依赖chromium的base、net等基础库,所以不得不对这些代码进行重写;


二是将原版使用了chromium的web相关功能,通过调用nodejs.dll提供的接口来实现。


其中web相关功能,我巧妙的通过miniblink导出的C接口来实现,而其nodejs相关,我是直接将nodejs的代码完整的编译进了nodejs.dll。


所以,这里说到的第二个nodejs.dll部分,其实已经不是网上原版的nodejs.dll了,而是我将miniblink的代码和nodej.dll的代码简单的编译在一个dll中所产生的文件。其中v8部分是共用的。所以仅仅在miniblink的基础上,增加了几M而已。


所以,这也解释了为什么每次发出来的编译好的miniblink的包,主dll都叫node.dll。因为需要伪装成nodejs。


但mini-electron和原版并不是完全一样。有个最大的不同在于,原版因为chromium的限制,必须使用多进程架构。了解electron使用方式的人都知道,


electron分成主进程和渲染进程。其中主进程跑了一个nodejs上下文环境,而每个渲染进程又跑了一个nodejs环境。
主进程同时也是chromium的主进程。

主进程的nodejs环境用来调用chromium的content
api来实现操纵chromium的web能力。


而mini-electron不同, 因为miniblink的架构本身就是单进程,所以为了简单起见,我使用单进程多线程来模拟electron多进程。其中,主线程一个nodejs环境,渲染线程跑一个miniblink的webview。注意,这里只有一个渲染线程,不管有多少个webview。这是blink的架构限制的。同时主线程通过

异步的调用miniblink的webview接口(又称为wke接口)来实现操纵web能力。


这也就造成了一个技术上的限制:mini-electron不能实现同时加载多个同样的原生dll(在nodejs里,这部分是以".node"结尾的文件)。


这是windows的dll加载机制限制。所以对于那些同时在主进程和渲染进程都加载了原生dll的应用,mini-electron会报错。例如vscode就在主进程和渲染

进程里都加载了keymap.node。


但这个限制是可以通过简单的改造js来绕过的。electron实现了remote功能,可以通过remote.require来指挥主进程去加载dll,并远程使用dll的接口。

我就稍微改了下keymap的js,便完美的跑起了vscode。事实上,应该不会有人真的需要两个进程同时使用一个dll。绝大部分情况可以通过remote来规避。

如何mini-electron模式


使用方式很简单。以vsocde为例。vscode的目录结构大概是这样的:


+VSCode-win32-ia32-1.23.1

|

+----Code.exe

|

+----node.dll

|

+----resources
|

+---app

|
+---electron.asar

其中code.exe是主程序,node.dll是nodejs的dll。resoures的app文件夹里存放了vscode的所有资源。electron.asar是electron的资源文件。


改造成使用mini-electron很简单,从github.com/weolar/minib里下载到最新包解压到miniblink-package文件夹后,取出mini-electron.exe、node.dll文件放入VSCode-win32-ia32-1.23.1目录下(其中node.dll会被覆盖),miniblink.asar放入resources目录下即可。此时运行mini-electron.exe即可看到效果。

当然,还有种更简单的方法,就是解压最新包后(例如叫miniblink-package),直接把vscode的resources\app文件夹拷入miniblink-package\resources\app。再运行mini-electron.exe即可。

其他electron app同样的使用方式。

当然,这里使用vscode举例其实不妥。因为vscode因为上述使用了多进程加载dll的缘故,直接跑是跑不起来的。需要将我修改后的node_modules.asar.unpacked文件夹覆盖掉原版的VSCode-win32-ia32-1.23.1\resources\app\node_modules.asar.unpacked文件夹。我这里有个已经打包好的精简版vscode可以直接运行看到效果:

https://pan.baidu.com/s/1hUu8DXcmK6y9OzmjJUS9LApan.baidu.com
忽略这丑丑的win 98风格主题
就这三文件,不能再多了


另外,如果运行过程中发现没有效果,可以打开dbgview(网上随处可下),再运行,看有什么log输出,再直接反馈给我(github.com/weolar/minib


mini-electron有哪些优势


先看electron有哪些劣势:

  • 安装包的大小难以优化,除非你搞明白vscode团队是如何做到的。
  • Electron因为需要一份chromium库的拷贝,因此再小的app,内存开销都不少。
  • 多个Electron运行,是不能共享主进程资源的,也无法做关联性的优化,浏览器是有一套IPC进程做所有调度的。能有开销上的优化。
  • 因为体积大,且每次打开新网页都要重新初始化,所以启动缓慢。


所以,electron的劣势正好就是mini-electron的优势。


此外,刚看到PWA也打算进军桌面市场。然而PWA只是一套标准,实现上还是得带上chromium。所以…

编辑于 2018-07-28

文章被以下专栏收录

    Electron 基于 Chromium 和 Node.js, 让你可以使用 HTML, CSS 和 JavaScript 构建应用。Electron 兼容 Mac, Windows 和 Linux。Electron 是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目。