发布网友 发布时间:2024-10-04 02:16
共1个回答
热心网友 时间:2024-10-08 18:24
前言Electron是使用JavaScript,HTML和CSS构建跨平台的桌面应用程序的框架,可构建出兼容Mac、Windows和Linux三个平台的应用程序。
一个跨端框架的设计,有三个问题需要考虑,分别是UI渲染、原生API以及客户端构建方式。Electron是如何解决上述问题的呐?
Electron的跨端原理并不难理解:它通过集成浏览器内核,使用前端的技术来实现不同平台下的渲染,并结合了Chromium、Node.js和用于调用系统本地功能的API三大板块。
Chromium为Electron提供强大的UI渲染能力,由于Chromium本身跨平台,因此无需考虑代码的兼容性。最重要的是,可以使用前端三板斧进行Electron开发。
Chromium并不具备原生GUI的操作能力,因此Electron内部集成Node.js,编写UI的同时也能够调用操作系统的底层API,例如path、fs、crypto等模块。
NativeAPI为Electron提供原生系统的GUI支持,借此Electron可以调用原生应用程序接口。
总结起来,Chromium负责页面UI渲染,Node.js负责业务逻辑,NativeAPI则提供原生能力和跨平台。
上面粗略讲解了Electron的跨端原理,下面我们来深究一下。
Chromium架构JavaScript是单线程语言,但浏览器是多线程的,Chromium作为Chrome的实验版,自然也是基于多线程工作机制。(图源:Chromium官网)
Chromium的多进程模式主要由三部分组成:浏览器端(Browser)、渲染器端(Render)、浏览器与渲染器的通信方式(IPC)
1.浏览器进程
浏览器进程Browser只有一个,当Chrome打开时,进程启动。浏览器为每个渲染进程维护对应的RenderProcessHost,负责浏览器与渲染器的交互。RenderViewHost则是与RenderView对象进行交互,渲染网页的内容。浏览器与渲染器通过IPC进行通信。
2.渲染进程管理
每个渲染进程都有一个全局RenderProcess对象,可以管理其与父浏览器进程之间的通信,并维护其全局状态。
3.view管理
每个渲染器可以维护多个RenderView对象,当新开标签页或弹出窗口后,渲染进程就会创建一个RenderView,RenderView对象与它在浏览器进程中对应的RenderViewHost和Webkit嵌入层通信,渲染出网页网页内容(这里是我们日常主要关注的地方)。
Electron架构解析Electron架构参考了Chromium的多进程架构模式,即将主进程和渲染进程隔离,并且在Chromium多进程架构基础上做一定扩展。
将上面复杂的Chromium架构简化:
Chromium运行时由一个BrowserProcess,以及一个或者多个RendererProcess构成。RendererProcess负责渲染页面Web,BrowserProcess负责管理各个RendererProcess以及其他功能(菜单栏、收藏夹等)
下面我们看一下啊Electron架构有那些变化?
Electron架构中仍然使用了Chromium的RendererProcess渲染界面,RendererProcess可以有多个,互相独立不干扰。由于Electron为其集成了Node运行时,RendererProcess可以调用NodeAPI。主要负责:利用HTML和CSS渲染页面;利用JavaScript实现页面交互效果。
相较于Chromium架构,Electron对Browser线程做了很多改动,将其更改名MainProcess,每个应用程序只能有一个主线程,主线程位于Node.js下运行,因此其可以调用系统底层功能。其主要负责:渲染进程的创建;系统底层功能及原生资源的调用;应用生命周期的控制(包裹启动、推出以及一些事件监听)
经过上面的分析,Electron多进程的系统架构可以总结为下图:
可以发现,主线程和渲染线程都集成了NativeAPI和Node.js,渲染线程还集成Chromium内核,成功实现跨端开发。
Node与ChromiumNode的事件循环与浏览器的事件循环有明显不同,Chromium既然是Chrome的实验版,自然与浏览器实现相同。
Node的事件循环基于libuv实现,而Chromium基于messagebump实现。主线程只能同时运行一个事件循环,因此需要将两个完全不同的事件循环整合起来。
有两种解决方案:
使用libuv实现messagebump将Chromium集成到Node.js
将Node.js集成到Chromium
Electron最初的方案是第一种,使用libuv实现messagebump,但不同的OS系统GUI事件循环差异很大,例如mac为NSRunLoop,Linux为glib,实现过程特别复杂,资源消耗和延迟问题也无法得到有效解决,最终放弃了第一种方案。
Electron第二次尝试使用小间隔的定时器来轮询GUI事件循环,但此方案CPU占用高,并且GUI响应速度慢。
后来libuv引入了backend_fd概念,backend_fd轮询事件循环的文件描述符,因此Electron通过轮询backend_fd来得到libuv的新事件实现Node.js与Chromium事件循环的融合(第二种方案)。
下面这张PPT完美的描述了上述过程(图源:Electron:TheEventLoopTightrope-ShelleyVohr|JSHeroes2019)
参考链接Multi-processArchitecture
EssentialElectron
跨平台技术实战!百度文库跨平台技术快速落地全过程
ElectronInternals:MessageLoopIntegration
Electron开发实战文档资料
?奖品大放送小包又来了,本次活动的奖励有两份:妖娆托举猫和马赛克线圈毛巾
参与方式:点赞或评论即可(友情提示,如果回复跨端相关的评论,运气可能会更好哦)
后语我是?战场小包?,一个快速成长中的小前端,希望可以和大家一起进步。
如果喜欢小包,可以在?掘金?关注我,同样也可以关注我的小小公众号——小包学前端。
一路加油,冲向未来!!!
疫情早日结束人间恢复太平原文:https://juejin.cn/post/7103337772424888356