转载自 | InfoQ
编译 | 核子可乐、褚杏娟
微软近期宣布,旗下 Teams 应用活跃用户已经达到惊人的 2.5 亿。这让 Teams 成了继 Word 和 Excel 之后,微软 Office 生产力套件中的又一位当红明星。然而,Teams 一直受到性能问题的困扰,用户们对此吐槽不断。
前不久,微软 Teams 高级副总裁宣布,Teams 将放弃使用 Electron,转而匹配微软自己的 Edge WebView2 渲染引擎以寻求性能提升。官方声称,调整之后 Teams 的内存消耗量将直接减半。
追求更低的内存占用
对于已经尝试了许多不同技术来减少桌面客户端所需内存的微软来说,这似乎是迈出的很大一步了。有很多网友表示很开心看到这一变化。
“Angular 也不见了。我们现在 100% 使用 reactjs。”Teams 工程师 Rish Tandon 在推特上表示。
根据 Teams 工程师 Rish Tandon 的说法,这项工作大概花费了 Teams 团队 6 个月的时间,优化后的 Teams 2.0 消耗的内存将只有 Teams 1.0 上相同帐户的一半。
时至今日,仍有众多知名应用都选用 Electron 来提供支持。Electron 框架能够帮助 Web 开发者将自己的 Web 应用发布至桌面平台,且不受任何特定平台的复杂性影响。但由于一切 Electron 应用程序后端都要运行只属于自己的 Chrome OS 实例,所以同时运行两个以上此类应用就会疯狂消耗主机资源。
于是,在 Electron 之上执行大量处理操作的 Teams 也无法避免地疯狂占用内存、拖慢计算机速度。微软甚至专门发布了文档页面,解释为什么 Teams 的内存占用量如此之高。
与 Electron 不同,WebView2 会监控 Chromium 的行为、检测还有多少系统内存可用,从而更有效地利用内存资源优化渲染体验。如果其他应用程序或服务需要系统内存,Chromium 就会将空间移交给这些进程。如此一来,内存容量较小的低端计算机也能带来不错的性能表现。
WebView2 更像是一种类似于应用窗口的控件,专门用于渲染 Web 页面。事实上,WebView2 控件还允许在原生应用程序中嵌入 Web 技术(包括 HTML、CSS 与 JavaScript)。所以要想将 Teams 规模的应用程序过渡至 WebView2,开发团队需要对大量由 Electron 提供的抽象进行重写。因此,Teams 在本质上将变得更接近于原生 Windows 应用程序。
目前,WebView2 已经被 Outlook 作为微软“One Outlook”项目的组成部分。
为什么选 Webview2 ?
Teams 需要处理大量音频与视频内容,所以微软认为最好能把一部分工作负载转移给 WebView2 更擅长的原生形式。事实也证明,Electron 抽象并不能有效完成这些处理任务。但从严格意义上来说,Webview2 并不属于 Electron 的替代方案。
Webview2 并不是 Electron 那样可以在桌面平台上快速发布 Web 应用的打包器。Electron 与 WebView2 都是以 Chromium 为基础构建而成,但更严格地说,WebView2 继承的是 Edge 源代码,而 Edge 又用到了 Chromium 源代码的一个分支。Electron 则不与 Chrome 共享任何 DLL。WebView2 二进制文件硬链接至 Edge(截至 Edge 90 的 Stable 版本),所以二者使用着相同的磁盘及其他一些工作集机制。
Electron 应用会始终捆绑并分发其开发过程中所使用的特定 Electron 版本。相比之下,WebView2 在发布方面则提供两个选项:可以直接捆绑应用开发时所使用的特定 WebView2 库,也可以使用系统上已经存在的共享运行时版本。WebView2 为这两种方法分别提供工具,包括一个防止共享运行时丢失的引导安装程序。而且从 Windows 11 版本开始,操作系统已经内置有 WebView2 运行时。
捆绑二者框架的应用程序负责保持框架更新,包括更新各次要安全增强版本。而对于使用共享 WebView2 运行时的应用程序,版本维护则依靠 WebView2 自己的更新程序,会以类似 Chrome 或 Edge 的方式独立于应用程序之外运行。WebView2 更新应用程序的代码或任何其他依赖项仍由开发者负责管理,这一点与 Electron 相同。值得注意的是,Windows 更新管理功能并未覆盖到 Electron 与 WebView2。
Electron 与 WebView2 都继承了 Chromium 的多进程架构——即由单一主进程同一个或多个渲染器进程通信。这些进程同系统上正在运行的其他应用程序完全分离,每个 Electron 应用程序都拥有一个独立的进程树,其中包含一个根浏览器进程、部分实用程序进程外加一定数量的渲染进程。与应用套件类似,使用相同用户数据文件夹的各 WebView2 应用程序之间会共享非渲染器进程,但使用不同数据文件夹的 WebView2 应用程序之间则不共享任何进程。
ElectronJS 流程模型:
基于 WebView2 的应用程序流程模型:
Electron 能够为各类常见桌面应用需求提供 API,例如菜单、文件系统访问、通知等等。WebView2 则能以组件的形式集成到 WinForms、WPF、WinUI 或者 Win32 等应用程序框架当中。另外,WebView2 仅通过 JavaScript 提供符合 Web 标准的操作系统 API。
Electron 当中集成有 Node.js,因此 Electron 应用程序可以使用来自渲染器及主进程的任何 Node.js API、模块或者 node-native-addon。WebView2 应用程序则不会对应用程序各个部分所使用的编程语言或框架做任何预设,JavaScript 代码必须通过 application-host 进程代理才能访问操作系统。
Electron 提供可配置的 Web 内容安全模型,配置范围涵盖完全开放访问到完全沙箱模式。WebView2 内容则始终保持沙箱化。Electron 还提供关于如何选择安全模式的详尽说明文档,而 WebView2 则提供丰富的安全最佳实践。
Electron 源代码在 GitHub 上进行维护与交付,各应用程序能够修改并构建属于自己的 Electron 品牌。WebView2 源代码则并未登陆 GitHub。
具体差异总结如下:
需要强调一点区别,这也是 Electron 应用程序中的一项重要性能考量因素。
性能差异有多大?
在 Chromium 当中,浏览器进程负责充当沙箱渲染器与系统其余部分之间的 IPC 代理。虽然 Electron 支持非沙箱渲染进程,但也有不少应用会选择启用沙箱以提升安全水平。WebView2 则始终启用沙箱,所以对于大多数 Electron 及 WebView2 应用程序而言,IPC 确实会影响到整体性能。
虽然 Electron 与 WebView2 的流程模型基本相似,但底层 IPC 却有所不同。JavaScript 与 C 或 C# 之间的通信需要经过编组,而且最常见的方法是编组为 JSON 字符串。请注意,JSON 序列化 / 解析操作的资源成本极高,因此 IPC 瓶颈必然会对性能产生负面影响。因此从 Edge 93 开始,WebView2 将对网络事件使用 CBOR。
Electron 则通过 MessagePorts API 支持任意两个进程之间的直接 IPC,其中使用到了结构化克隆算法。利用这项功能,应用程序就能避免在不同进程间发送对象时执行资源成本高昂的 JSON 序列化操作。
Electron 与 WebView2 虽然有着不少差异之处,但二者在渲染 Web 内容方面却高度一致。最核心的影响还是来自应用程序架构与 JavaScript 库 / 框架在内存与性能层面的影响,毕竟同样师出 Chromium。
本文的原标题为《仅仅过去 4 年,微软最终放弃了 Electron》,我看到很是惊讶“微软这是要始乱终弃了吗?“
Electron 是 GitHub 开发的开源框架,而且 GitHub 的 Atom 和微软的 VSCode 编辑器用的都是它。我还特地去确认了下 VSCode 项目的依赖,截止本文发布的时候 VSCode 还是基于 Electron 构建,同时 Electron 最近一次提交是 24 小时内。怎么就被放弃了呢?
看完文章我才明白,原来是微软的 Teams 应用因为性能问题不再用 Electron 框架,改用自家的 WebView2 了,微软方面(GitHub)并没有宣布放弃和停止维护 Electron,所以大家还可以放心使用。但 Electorn 性能、占资源方面确实也饱受诟病,除了 WebView2 还有没有其它的框架和解决方案呢?欢迎留言讨论。
Electron:https://github.com/electron/electron
WebView2:https://docs.microsoft.com/zh-cn/microsoft-edge/webview2