乐趣区

关于web:浅谈基于Web的跨平台桌面应用开发

作者:京东物流 王泽知

近些年来,跨平台跨端始终是比拟热门的话题,Write once, run anywhere,始终是咱们开发者所冀望的,跨平台计划的劣势非常显著,对于开发者而言,能够做到一次开发,多端复用,一套代码就可能运行在不同设施上,这在很大水平上可能升高研发老本,同时可能在产品效力上做到疾速验证和疾速上线。现在跨端跨平台的优良技术计划也比拟多,

  • 挪动端:React Native,Flutter,Weex;
  • 小程序端:Taro,Uniapp;
  • 桌面端:NW.js,Electron,Flutter for desktop,Tauri,Wails,

明天咱们聊聊桌面利用开发。

[]()1 什么是跨平台

泛指编程语言、软件或硬件设施能够在多种操作系统或不同硬件架构的电脑上运作。一般来说,有这几种场景,别离是跨设施平台(如 PC 端和挪动端),跨操作系统,(挪动端中分 Android,IOS,PC 端中分 Windows,macOS,Linux),国内的小程序(微信,京东,百度,支付宝,字节跳动等等)

[]()2 跨平台的技术计划

跨平台编程不是一件容易的事件,这是因为在不同平台之间,有许多小而简单的差别,这都须要思考周全,当初咱们有了成熟的跨平台技术计划,可能减小开发者的开发成本及跨平台的难易水平。

  • NW.js
  • Electron
  • Flutter for Desktop
  • Tauri
  • Wails

[]()2.1 NW.js

官网:https://nwjs.io/
GitHub:https://github.com/nwjs/nw.js
语言:Nodejs + 前端任意框架
代表我的项目:微信小程序 IDE,京东小程序 IDE

NW.js(node-webkit)是一个基于 Chromium 和 Node.js 的 Web 运行环境,可让你间接在 DOM 中调用 Node.js 模块,并可应用任何现有的 Web 技术来编写本地利用。

[]()2.2 Electron

官网:https://www.electronjs.org/
GitHub:https://github.com/electron/electron
语言:Nodejs + 前端任意框架
代表我的项目:VSCode,百度小程序 IDE,京 ME,Facebook Message,

Electron 的前身叫做 Atom-Shell,原本是 GitHub 公布开源编辑器 Atom 时一并公布的副产物,然而起初这个副产物的影响力远远的超过了 Atom 自身,于是便改名为一个独立专案,也就是当初的 Electron。Electron 的实质很简略,就是 Chromium + Node.js 的组合,两者之间透过 IPC 通信。
相似于 NW.js,外表上,它们仿佛十分类似,然而这两个我的项目有着实质上的区别,使得 Electron 和 NW.js 成为两个齐全独立的产品。

  • 利用入口不同,NW.js 主入口是一个 HTML,Electron 中是 JavaScript,可操作性更强
  • Node 集成形式不同,在 NW.js 中网页中的 Node 须要通过给 Chromium 打补丁来实现,Electron 则是通过各个平台的音讯循环与 libuv 的循环集成,防止了间接在 Chromium 上做改变
  • 性能,反对的性能数量上有显著的差距,Electron 有着较大的社区及社区活跃度,大量成熟的 npm 功能模块。

[]()2.3 Tauri

官网:https://tauri.app/
GitHub:https://github.com/tauri-apps/tauri
语言:Rust + 前端任意框架
代表我的项目:仅有大量开源利用

Tauri 是 2021 年 JavaScript 明星我的项目(https://risingstars.js.org/2021/zh#section-all)的最受欢迎项 …)中 满意度和关注度排名第 1,因为 Vite,esbuild,swc,Rome 等工具的大火,让基于 Go、Rust 的高效率构建类工具进入暴发期,加上 Bundleless 的构建体验,让 Rust、Go 成为前端开发者的又一扇门。因为 Tauri 的 Rust 背景,加上构建产物小,内存占用低,还是值得长期关注的。

题外话:
Rust 前景还是十分不错的,如 Linux 内核接收 Rust,deno 采纳 Rust,微软拥抱 Rust,fuchsia 的 Rust 代码占比超 50%,Apple 在底层 all-in rust,间断 6 年的 stackoverflow 最受欢迎语言。就是学习门槛略微有点高

[]()2.4 Wails

官网:https://wails.io/
GitHub:https://github.com/wailsapp/wails
语言:Go + 前端任意框架
代表我的项目:暂无

Wails 是一个可让您应用 Go 和 Web 技术编写桌面利用的我的项目。
将它看作为 Go 的快并且轻量的 Electron 替代品。您能够应用 Go 的灵活性和弱小性能,联合丰盛的古代前端,轻松的构建应用程序。与 Tauri 相似,Windows 上应用的是 Webview2。

[]()2.5 Flutter for Desktop

官网:https://flutter.dev/multi-platform/desktop
GitHub:https://github.com/flutter/flutter
语言:Dart
代表我的项目:暂无

从渲染原理看 Flutter 是 skia 自绘性能优于 Electron,但须要思考下稳定性和生态。

[]()3 跨平台的架构原理

本次咱们探讨下用的最多的 Electron 和比拟有前景的 Tauri 的架构原理。

通过 Web 技术写 UI,赋予了底层能力,达到跨平台的能力及体验。

[]()3.1 Chromium 多过程架构

大多数古代 Web 浏览器都为多过程架构,次要有浏览器主过程、渲染过程、插件过程、网络过程、GPU 过程,Chromium 也是如此。

IPC = Inter-Process Communication 过程间通信

Chromium 是 Chrome 的开源版,同时也是一个浏览器。

  • 主过程的 RenderProcessHost 和渲染过程的 RenderProcess 负责解决 IPC 事件
  • 渲染过程的 RenderView,页面的展现就是在这里基于 Webkit 排版进去的
  • ResourceDispatcher 解决资源申请,当页面须要申请资源时,通过 ResourceDispather 创立一个申请 ID 转发到 IPC,在 Browser 过程中解决后返回

[]()3.2 Electron 架构

  • 在每个过程中裸露了 Native API(Main Native API,Renderer Native API)
  • 引入 Node.js
  • Web 技术实现 UI

[]()3.3 Electron 过程模型

Electron 继承了来自 Chromium 的多过程架构,这使得此框架在架构上十分类似于一个古代的网页浏览器。

为何采纳多过程架构?
网页浏览器是个极其简单的应用程序。除了显示网页内容的次要能力之外,他们还有许多次要的职责,例如:治理泛滥窗口 (或 标签页) 和加载第三方扩大。
在晚期,浏览器通常应用单个过程来解决这些性能。这种模式尽管能减小关上每个标签页的开销,但也同时意味着一个网站的解体或无响应会影响到整个浏览器。
为了解决这个问题,Chrome 团队决定让每个标签页在本人的过程中渲染,从而限度了一个网页上的有误或恶意代码可能导致的对整个应用程序造成的挫伤。而后用单个浏览器过程管制这些标签页过程,以及整个应用程序的生命周期

Electron 也是这样,作为利用开发者,管制着两种类型的过程,主过程和渲染过程。
主过程负责应用程序窗口治理,应用程序的生命周期,原生 API 等
渲染过程负责 UI 的展现,这部分咱们能够抉择任意前端框架 Vue、React、Svelte、Preact

[]()3.4 Tauri 过程模型

Tauri 采纳了一种相似 Electron 和大多数古代 Web 浏览器那样的多过程架构。包含主过程和 WebView 过程,单个主过程治理一个或多个 WebView 过程。

[]()3.5 过程间通信

Electron 的过程通信
渲染器过程 -> 主过程

  • (单向)ipcRenderer.send API 发送音讯,而后应用 ipcMain.on API 接管
  • (双向)ipcRenderer.invoke 与 ipcMain.handle 搭配应用来实现

[]()4 实战 – 导航启动工具

为了比照 Electron 和 Tauri 差异性,别离用 Electron 和 Tauri 做一个简略的利用,导航启动器,相似 Alfred,Spotlight。

[]()4.1 性能形容

首先形容下这个利用的性能,启动利用后,通过快捷键 Ctrl/Command + K 唤起利用界面 – 一个输入框,在输入框输出关键词 git 会展现 git 相干的零碎名称列表,抉择后回车即可关上 github.com,相当于另类的书签。

[]()4.2 设计思路

[]()4.3 我的项目构造及实现

这里 Electron 应用的是 Electron React Boilerplate 脚手架,应用 webpack 构建 UI 局部
Tauri 是应用官网的脚手架工具 – create-tauri-app,内置了 Vite,在前端框架上选了 React

这个导航启动器次要波及的性能点有:

  1. 整个利用不展现敞开,最小化,最大化的按钮及整个菜单栏(menuBar),无边框窗口
  2. 视觉上整个利用是一个输入框,利用窗口的高度是依据网页内容的高度自适应
  3. 注册全局快捷键,显示利用,暗藏利用
  4. 监听按键,并应用默认浏览器关上链接

[]()4.3.1 对于性能点一

Electron 是通过对主窗口初始化时批改配置,frame 设置成 false 可实现无边框窗口

在 Tauri 中,实现无边框窗口有 3 种形式:通过 tauri.conf.json 配置,通过 Tauri 提供的 JS API – @tauri-apps/api,通过 Rust 原生批改 window;这里咱们选用在 tauri.config.json 中配置

[]()4.3.2 对于性能点二

输入框局部均由 React 实现,次要的差别在窗体依据内容高度动静调整窗体的高度,就是依据 document.body.offsetHeight 的高度去设置 mainWindow 的高度
在 Electron 中,能够在渲染过程中发 IPC 告诉主过程去批改,主过程监听到音讯后进行高度批改

在 Tauri 中,绝对比拟不便,对于罕用的性能都封装了 JS API,也就是后面提到的 @tauri-apps/api,间接导入办法调用即可

[]()4.3.3 对于性能点三

注册全局快捷键,管制 mainWindow 的显示和暗藏
在 Electron 中,首先定义 registerGlobalShortcut 办法,在 app 启动后注册快捷键,次要是在主过程中操作。

在 Tauri 中,得益于 JS API 的便利性,在渲染过程中就能够注册,因而只须要在 React 生命周期中执行注册

[]()4.3.4 对于性能点四

不便演示,咱们这里间接对 document.body 进行 onkeydown 监听,高低光标抉择对应的选项,回车或点击应用默认浏览器关上对应的链接,这里两者的实现很类似

至此,次要性能曾经实现,下一步进入看下如何打包多平台的利用。

[]()4.4 利用打包

Electron 中比拟常见的有两种打包,electron-packager 和 electron-builder,electron-builder 的生态更好,咱们这里抉择 electron-builder。

Tauri 中则是内置在 cli 的打包计划,执行 yarn tauri build 即可

同一利用比照,雷同 React 版本,未应用 UI 框架

通过以上数据比照根本与 Tauri 主页上的数值相符,较小的体积,内存占用小。

[]()4.5 利用更新

两者都有对应的解决方案,具体内容能够看下官网文档,本文不做过多介绍。

[]()5 总结

NW.js 的时代曾经过来,思考 NW.js 的能够优先 Electron。
Tauri 体现不错,前景看好。它解决了 Electron 现有的很多问题,带来了简略便捷的开发体验,也期待 Tauri 的 roadmap 中集成 Deno 作为利用的后端解决,这样就能够持续应用 JavaScript/TypeScrupt 来实现利用后端逻辑,新我的项目能够思考应用,然而还有一些问题须要改良以及 Rust 的学习曲线波折,有肯定的学习老本。
Electron 目前仍是最多的抉择,得益于本身宏大的社区,丰盛的性能及工程实际,性能优化这部分比拟考验开发者。

退出移动版