Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1
               本文由京東技術王澤知分享,原題“基于Web的跨平臺桌面應用開發”,下文進行了排版和內容優化。

          1、引言

          近些年來,跨平臺跨端一直是比較熱門的話題,Write once, run anywhere一直是開發者所期望的,跨平臺方案的優勢十分明顯。

          對于開發者而言,可以做到一次開發、多端復用,一套代碼就能夠運行在不同設備上,這在很大程度上能夠降低研發成本,同時能夠在產品效能上做到快速驗證和快速上線。

          如今跨端跨平臺的優秀技術方案也比較多:

          • 1)移動端:React Native,Flutter,Weex;
          • 2)小程序端:Taro,Uniapp;
          • 3)桌面端:NW.js,Electron,Flutter for desktop,Tauri,Wails。

          本文主要介紹了目前比較流行的桌面應用跨平臺開發技術及其架構,并以實戰的方式對比了 Electron 和 Tauri 的優勢和劣勢,以及桌面跨平臺應用開發的技術趨勢。

          2、系列文章

          本文是系列文章中的第 13篇,本系列總目錄如下:

          3、什么是跨平臺

          泛指編程語言、軟件或硬件設備可以在多種操作系統或不同硬件架構的電腦上運作。

          一般來說,有這幾種場景,分別是跨設備平臺(如 PC 端和移動端),跨操作系統(移動端中分Android,IOS,PC端中分 Windows,macOS,Linux),國內的小程序(微信,京東,百度,支付寶,字節跳動等等)。

          4、跨平臺技術方案盤點

          4.1概述

          跨平臺編程不是一件容易的事情,這是由于在不同平臺之間,有許多小而復雜的差異,這都需要考慮周全。

          目前已經有了較多成熟的跨平臺技術方案,能夠減小開發者的開發成本及跨平臺的難易程度。

          比如:

          • 1)NW.js;
          • 2)Electron
          • 3)Flutter for Desktop;
          • 4)Tauri;
          • 5)Wails;

          4.2NW.js

          NW.js 官網描述:

          NW.js概況:

          NW.js(node-webkit )是一個基于 Chromium 和 Node.js 的 Web 運行環境,可直接在 DOM 中調用 Node.js 模塊,并可使用任何現有的 Web 技術來編寫本地應用。

          4.3Electron

          Electron 官網描述:

          Electron概況:

          Electron 的前身叫做 Atom-Shell,本來是 GitHub 發布開源編輯器 Atom 時一并發布的副產物,但是后來這個副產物的影響力遠遠的超過了 Atom 本身,于是便改名為一個獨立專案,也就是現在的 Electron。Electron 的本質很簡單,就是 Chromium + Node.js 的組合,兩者之間通過 IPC 通訊。

          類似于 NW.js,表面上,它們似乎非常相似,但是這兩個項目有本質上的區別,使得 Electron 和 NW.js 成為兩個完全獨立的產品。

          比如:

          • 1)應用入口不同:NW.js 主入口是一個 HTML,Electron 中是 JavaScript,可操作性更強;
          • 2)Node 集成方式不同:在 NW.js 中網頁中的 Node 需要通過給 Chromium 打補丁來實現,Electron 則是通過各個平臺的消息循環與 libuv 的循環集成,避免了直接在 Chromium 上做改動;
          • 3)支持的功能數量上有明顯的差距:Electron 有著較大的社區及社區活躍度,大量成熟的 npm 功能模塊。

          4.4Tauri

          Tauri 官網描述:

          Tauri概況:

          Tauri 是 2021年 JavaScript 明星項目的最受歡迎項目中排名第5,在 stateofjs 2021 中 滿意度和關注度排名第1, 由于 Vite,esbuild,swc,Rome 等工具的大火,讓基于 Go、Rust 的高效率構建類工具進入爆發期,加上 Bundleless 的構建體驗,讓 Rust、Go 成為前端開發者的又一扇門。由于 Tauri 的 Rust 背景,加上構建產物小,內存占用低,還是值得長期關注的。

          Tauri 在 JavaScript 明星項目和 stateofjs 中的排名:

          題外話:Rust 前景還是非常不錯的,如 Linux內核接納 Rust,deno采用 Rust,微軟擁抱Rust,fuchsia 的 Rust 代碼占比超50%,Apple 在底層 all-in rust,連續6年的 stackoverflow 最受歡迎語言,但學習門檻較高。

          4.5Wails

          Wails 官網描述:

          Wails概況:

          Wails 是一個可讓您使用 Go 和 Web 技術編寫桌面應用的項目。可以將其看作為 Go 的快并且輕量的 Electron 替代品。可以使用 Go 的靈活性和強大功能,結合豐富的現代前端,輕松的構建應用程序。

          與 Tauri 類似,Windows 上使用的是 Webview2。

          4.6Flutter for Desktop

          Flutter 官網描述:

          Flutter概況:

          從渲染原理看 Flutter 是 skia 自繪性能優于 Electron,但需要考慮下穩定性和生態。

          5、典型跨平臺架構的技術原理

          5.1概述

          本節將討論使用較多的 Electron 和較有前景的 Tauri 的架構原理。

          Electron 架構組成:

          通過 Web 技術寫 UI,賦予了底層能力,達到跨平臺的能力及體驗。

          5.2Chromium 多進程架構

          大多數現代 Web 瀏覽器都為多進程架構,主要有瀏覽器主進程、渲染進程、插件進程、網絡進程、GPU 進程,Chromium 也是如此。

          IPC = Inter-Process Communication 進程間通信

          Chromium 架構圖:

          Chromium 是 Chrome 的開源版,同時也是一個瀏覽器:

          • 1)主進程的 RenderProcessHost 和渲染進程的 RenderProcess 負責處理 IPC 事件;
          • 2)渲染進程的 RenderView,頁面的展示會在這里基于 Webkit 排版出來;
          • 3)ResourceDispatcher 處理資源請求,當頁面需要請求資源時,通過 ResourceDispather 創建一個請求 ID 轉發到 IPC,在 Browser 進程中處理后返回。

          5.3Electron 架構

          Election 架構圖:

          如上圖所示:

          • 1)在每個進程中暴露了 Native API(Main Native API,Renderer Native API);
          • 2)引入 Node.js;
          • 3)Web 技術實現 UI。

          5.4Electron 進程模型

          Electron 繼承了來自 Chromium 的多進程架構,這使得此框架在架構上非常相似于一個現代的網頁瀏覽器。

          為何采用多進程架構?

          網頁瀏覽器是個極其復雜的應用程序。除了顯示網頁內容的主要能力之外,它還有許多次要的職責,例如:管理眾多窗口 ( 或標簽頁) 和加載第三方擴展。

          在早期,瀏覽器通常使用單個進程來處理這些功能。這種模式雖然能減小打開每個標簽頁的開銷,但也同時意味著一個網站的崩潰或無響應會影響到整個瀏覽器。

          為了解決這個問題,Chrome 團隊決定讓每個標簽頁在自己的進程中渲染, 從而限制一個網頁上的有誤或惡意代碼可能導致的對整個應用程序造成的傷害,然后用單個瀏覽器進程控制這些標簽頁進程,以及整個應用程序的生命周期。

          多進程架構:

          Electron 也是如此,作為應用開發者,控制著兩種類型的進程,主進程和渲染進程:

          • 1)主進程負責應用程序窗口管理,應用程序的生命周期,原生API等;
          • 2)渲染進程負責UI的展示,這部分可以選擇任意前端框架 Vue、React、Svelte、Preact。

          5.5Tauri 進程模型

          Tauri 采用了一種類似 Electron 和大多數現代Web瀏覽器那樣的多進程架構。包括主進程和 WebView進程,單個主進程管理一個或多個 WebView 進程。

          Tauri 進程模型:

          5.6進程間通信

          Electron 的進程通信:(渲染器進程 -> 主進程)

          • 1)(雙向)ipcRenderer.invoke 與 ipcMain.handle 搭配使用來完成;
          • 2)(單向)ipcRenderer.send API 發送消息,然后使用 ipcMain.on API 接收。

          大多數現代 Web 瀏覽器都為多進程架構,主要有瀏覽器主進程、渲染進程、插件進程、網絡進程、GPU 進程,Chromium 也是如此。

          6、Electron和Tauri的實戰對比

          為了對比 Electron 和 Tauri 差異性,可以分別用 Electron 和 Tauri 做一個簡單的實戰應用——導航啟動器,類似于 Alfred、Spotlight。

          6.1功能描述

          首先來描述下這個應用的功能,啟動應用后,通過快捷鍵 Ctrl/Command + K 喚起應用界面——一個輸入框,在輸入框輸入關鍵詞 git 會展示 git 相關的系統名稱列表,選擇后回車即可打開 github.com,相當于另類的書簽。

          6.2設計思路

          導航啟動工具流程圖:

          6.3項目結構及實現

          Electron 使用的是 Electron React Boilerplate 腳手架,使用 webpack 構建 UI 部分。

          Tauri 是使用官方的腳手架工具——create-tauri-app,內置了 Vite,在前端框架上選了 React。

          Electron 與 Tauri 項目結構圖:

          這個導航啟動器主要涉及的功能點有:

          • 1) 整個應用不展示關閉,最小化,最大化的按鈕及整個菜單欄(menuBar),無邊框窗口;
          • 2) 視覺上整個應用是一個輸入框,應用窗口的高度是根據網頁內容的高度自適應;
          • 3) 注冊全局快捷鍵,顯示應用,隱藏應用;
          • 4) 監聽按鍵,并使用默認瀏覽器打開鏈接。

          7、Electron和Tauri具體功能點的代碼實現對比

          7.1功能點一

          Electron 通過對主窗口初始化時修改配置,frame 設置成 false 可實現無邊框窗口。

          Election 配置:

          在 Tauri 中,實現無邊框窗口有 3 種方式:

          • 1)通過 tauri.conf.json 配置;
          • 2)通過 Tauri 提供的 JS API - @tauri-apps/api;
          • 3)通過 Rust 原生修改 window。

          這里我們選用在 tauri.config.json 中配置。

          Tauri 配置:

          7.2功能點二

          其輸入框部分均由 React 實現,主要的差異在窗體根據內容高度動態調整窗體的高度,根據 document.body.offsetHeight 的高度設置 mainWindow 的高度;在 Electron 中,可以在渲染進程中發 IPC 通知主進程去修改,主進程監聽到消息后進行高度修改。

          Electron IPC 通信修改:

          在 Tauri 中,相對比較方便,對于常用的功能都封裝了 JS API,也就是前面提到的 @tauri-apps/api,直接導入方法調用即可。

          Tauri 在渲染進程修改:

          7.3功能點三

          注冊全局快捷鍵,控制 mainWindow 的顯示和隱藏。在 Electron 中,首先定義 registerGlobalShortcut 方法,在 app 啟動后注冊快捷鍵,主要是在主進程中操作。

          Election 注冊快捷鍵:

          在 Tauri 中,得益于 JS API 的便利性,在渲染進程中就可以注冊,因此只需要在 React 生命周期中執行注冊。

          Tauri 注冊快捷鍵:

          7.4功能點四

          為了方便演示,將直接對 document.body 進行 onkeydown 監聽,上下光標選擇對應的選項,回車或點擊使用默認瀏覽器打開對應的鏈接,這里兩者的實現很相似。

          Electron 與 Tauri 打開 URL:

          至此,主要功能已經完成,下一步將進入打包多平臺的應用方式。

          8、Electron和Tauri的應用打包對比

          Electron 中比較常見的有兩種打包:

          • 1)electron-packager;
          • 2)electron-builder。

          electron-builder 的生態更好,這里選擇 electron-builder。

          Electron 打包:

          PS:Electron的打包實踐可以看看《Electron初體驗(快速開始、跨進程通信、打包、踩坑等)》一文中的“7、打包發布”章節。

          Tauri 中則是內置在 cli 的打包方案,執行 yarn tauri build 即可。

          同一應用對比,相同 React 版本,未使用 UI 框架:

          內存占用對比圖:

          Tauri 官方對比圖:

          9、Electron和Tauri的應用更新對比

          兩者都有對應的解決方案,具體內容可以查看官方文檔。

          PS:關于Electron的版本列新實踐可以看看《vivo的Electron技術棧選型、全方位實踐總結》。

          10、本文小結

          NW.js 的時代已經過去,考慮 NW.js 的可以優先 Electron。

          Tauri 表現不錯,前景較好。它解決了 Electron 現有的很多問題,帶來了簡單便捷的開發體驗,也期待 Tauri 的 roadmap 中集成 Deno 作為應用的后端處理,這樣就可以繼續使用 JavaScript/TypeScrupt 來實現應用后端邏輯,新項目可以考慮使用,但是還有一些問題需要改進以及 Rust 的學習曲線曲折,有一定的學習成本。

          Electron 目前仍是最多的選擇,得益于自身龐大的社區,豐富的功能及工程實踐,但性能優化這部分比較考驗開發者。

          11、參考資料

          [1] Electron官方開發者手冊

          [2] Flutter官方手冊

          [3] Tauri官方手冊

          [4] React Native開發指南

          [5] 快速了解新一代跨平臺桌面技術——Electron

          [6] Electron初體驗(快速開始、跨進程通信、打包、踩坑等)

          [7] vivo的Electron技術棧選型、全方位實踐總結

          [8] 蘑菇街基于Electron開發IM客戶端的技術實踐

          [9] 融云基于Electron的IM跨平臺SDK改造實踐總結

          [10] 網易云信基于Electron的IM消息全文檢索技術實踐

          [11] 得物基于Electron開發客服IM桌面端的技術實踐

          [12] 新QQ桌面版為何選擇Electron作為跨端框架

          [13] 快速選型跨平臺框架Electron、Flutter、Tauri、React Native等


          (本文已同步發布于:http://www.52im.net/thread-4675-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 桐柏县| 深泽县| 牟定县| 乌鲁木齐市| 公主岭市| 汾阳市| 渝中区| 昌邑市| 玉屏| 七台河市| 邻水| 墨竹工卡县| 宁明县| 黑山县| 吉隆县| 灵丘县| 玉山县| 长葛市| 雅安市| 永丰县| 获嘉县| 沁水县| 旬阳县| 名山县| 扶沟县| 平湖市| 拜泉县| 万山特区| 喜德县| 徐闻县| 闻喜县| 宕昌县| 榆树市| 津市市| 家居| 新泰市| 吴川市| 中宁县| 榆树市| 丹江口市| 锦屏县|