Categories
程式開發

5000字解析:前端五種跨平台技術


本文不涉及到任何代碼,只講概念層面的,結合本人在實際開發過程中的各種體驗,對這幾種跨平台技術進行一個點評。

跨平台技術的由來

傳統的純原生開發已經不能滿足日益增長的業務需求。主要表現在如下兩個方面。

  1. 動態化內容需求增大。當需求發生變化時,純原生應用需要通過版本升級來更新內容,但應用上架、審核是需要周期的,這個週期對高速變化的互聯網時代來說是很難接受的,所以,對應用動態化(不發版也可以更新應用內容) 的需求就變得迫在眉睫了。

  2. 業務需求變化快,開發成本變大。由於原生開發一般都要維護 Android、iOS 兩個開發團隊,版本迭代時,無論人力成本還是測試成本都會變大。

總結一下,純原生開發主要面臨動態化和開發成本兩個問題,而針對這兩個問題,又誕生了一些跨平台的動態化框架。

跨平台技術簡介

針對原生開發麵臨的問題,人們一直都在努力尋找好的解決方案,然而時至今日,已經存在很多跨平台框架(注意,本書中所指的“跨平台”若無特殊說明,即特指Android 和iOS 兩個平台),根據其原理,主要可分為如下三類。

  1. H5(HTML5)+ 原生 ( Cordova、 Tonic、微信小程序)。

  2. Javascript 開發 + 原生渲染 ( React Native、Weex、快應用)。

  3. 自繪 U+ 原生 ( QT Mobile、 Flutter)。

接下來,我們將逐個來了解這三類框架的原理及優缺點。

1.12 Hybrid 技術簡介

H5+ 原生混合開發

這類框架的主要原理是將APP 需要動態變動的一部分內容通過H5 來實現,通過原生的網頁加載控件Webview( Android) 或WK Webview(iOS) 來加載(以後若無特殊說明,本書將用Webview來統一指代Android 和iOS 中的網頁加載控件)。這樣,H5 部分就可以隨時改變而不用發版,動態化需求得到滿足; 同時,由於H5 代碼只需要一次開發,就能同時在Android 和iOS 兩個平台上正常運行,這也可以降低開發成本,也就是說,H5 部分的功能越多,開發成本就越小。我們稱這種H5+ 原生的開發模式為混合開發,對於採用混合模式開發的APP,我們稱之為混合應用或Hybrid APP,如果一個應用的大多數功能都是採用H5 實現的話,我們稱其為Web APP。

目前混合開發框架的典型代表有 Cordova、 lonic 和微信小程序,值得一提的是,微信小程序目前是在 Webview 中渲染的。並非原生渲染,但將來有可能會採用原生渲染。

混合開發技術點

如之前所述,原生開發可以訪間平台的所有功能,而在混合開發中,H5 代碼是運行在Web View 中的, Webview 實質上就是一個瀏覽器器內核、其script 依然運行在一個權限受限的沙箱中,所以對大多數係統能力都沒有訪向權限、如無法訪向文件系統、不能使用藍牙等,所以,對於H5 不能實現的功能,都需要原生來實現。

而混合框架一般都會在原生代碼中預先實現一些訪問系統能力的API,然後暴露給Webview 以供Javascript 調用,這樣一來, Webview 就成為Javascript 與原生AP 之間通信的橋樑,主要負責Javascript 與原生之間調用消息的傳遞,而消息的傳遞必須遵守一個標準的協議,其規定了消息的格式與含義,我們將依賴於Webview 的、用於在Javascript 與原生之間通信並實現了某種消息傳輸協議的工具稱為Webview Javascript Bridge,簡稱Jsbridge,它也是混合開發框架的核心.

我所使用的跨平台技術:

  • Electron
  • React-Native
  • Taro
  • Cordova
  • 快應用
  • Flutter(剛學習)

排名由前往後,除了 Flutter 沒有使用過在商業項目中

Electron 的核心:

Electron 就是把 Node.js 的運行環境和谷歌瀏覽器內核一起打包了,於是就擁有了 Node.js 和 H5 技術的融合能力,又因為是基於 C++ 編寫,於是可以跨平台。 Mac、Windows、Linux。

工具類的軟件是最複雜的,例如vscode、word 這些,都是極度複雜的,又因為可以調用addon、各種腳本插件,原生第三方插件,這個技術簡直就是黑科技,至今我也不敢說對它熟悉。但是 APP Store 已經不能上線 Electron 應用了,而且打包簽名服務器也經常掛

特別注意:Electron 開發出來的東西是軟件,是一個安裝在電腦上的軟件!

我的 GitHub 可能有你想要的 Demo 內容:

https://github.com/JinJieTan

要想開發好Electron,要擁有一名C++ 人員專門編寫插件,一位後端出生的人生操作sqlite 數據庫(數據庫升級雖然可以兼容老版本,但是複雜的應用設計得不好數據庫就完了),一位前後端都懂並且熟悉調用操作系統插件的全棧工程師開發,這樣才能hold 得住複雜應用。如果你說這樣是不是太浪費了,那我覺得你沒有開發過複雜的軟件,一個好的軟件(客戶端),要考慮程序反編譯(保護)、奔潰守護進程等異常蒐集、用戶自動升級(差量or 全量)、本地數據庫加密、通信、激活喚醒。 。 。 。太多了,但是大部分前端做的就是後台管理系統,這也是一個悲劇。 。 。面試造火箭像以前我就做過將微信和 QQ 裡面一些插件拿出來經過一些處理用在項目裡,至此打開了新世界, 總之 Electron 非常考驗技術,是晉升偽全棧工程師最快的路徑。

推薦學習指數:五顆星

React-native

去年愛彼迎把 APP 的技術從 RN 換回了原生,首先它是外企,它可能某種程度上,使用 RN 會比國內有更大的優勢,獲得更大的支持。就像你使用Taro,那麼你有可能在論壇上找到它的負責人,提出想要的支持,最後它真的支持了(這個是存在的,如果你想認識可以幫你聯繫,我也在建議身邊人使用Taro)。

回到正題:

難道 RN 死了嗎?

JQuery 都沒死,它會死嗎?當然不會! RN 的生態非常強大,它開發出來的,也是真正的原生應用,它的原理如下:

在 React-native 文件中編寫的代碼,會在內存中生成虛擬 DOM 對象(其實就是一個 JS 對象),然後再通過 javaScriptCore (IOS 自帶,安卓不是,所以 RN 打包後安卓的包比蘋果大) 映射成原生控件樹。很多 jsBridge 都是基於 javaScriptCore 實現的。

例如:

iOS 代码发送通知:
// 需要包含的头文件
#import 
#import 
[self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
                                               body:@{@"name": @"nnnnnnn"}];
RN 代码接收通知:
// 创建一个监听收到的通知,需要组件 NativeAppEventEmitter
var listener = NativeAppEventEmitter.addListener(
'EventNotification', // 监听的通知名称
    (reminder) => console.log(reminder.name, '收到的通知')
);

提示:跨平台不是什麼高深的技術,只要搞懂它的運行機制原理,就好開發,定位問題。

那麼 RN 有什麼缺點呢?例如頻繁setState,可能會造成卡頓(做動畫的時候容易掉幀,特別是性能差的手機),但是也是可以使用一些技術優化盡量避免,跟是誰寫的有很大關係,還有就是項目變得特別大,跟原生交互特別多,特別複雜的應用,跨平台遇到的問題兼容處理也會越來越多,這也是為什麼愛彼迎會換回原生的原因,維護確實比較麻煩,還有版本環境的問題,有可能你升級了以後再也啟動不了了。 。 。

推薦理由:開發快速,生態成熟,使用 React 的 JSX 語法和 FLex 佈局快速開發原生應用。

推薦學習指數:四顆星

Taro

小程序跨平台開發,一款可以用 TSX、JSX 和 React 語法開發小程序的框架,內置了一些 UI 組件,還有物料市場,目前看勢頭很好。還可以集成 React-native, 真正做到一套代碼多處運行,不僅能編譯成各種平台小程序,還可以是 RN 的應用~ 666 , 還支持 快應用:

https://taro.aotu.io/

現如今市面上端的形態多種多樣,Web、React-Native、微信小程序等各種端大行其道,當業務要求同時在不同的端都要求有所表現的時候,針對不同的端去編寫多套代碼的成本顯然非常高,這時候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。

使用Taro,我們可以只書寫一套代碼,再通過Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/ 百度/ 支付寶/ 字節跳動/QQ/ 京東小程序、快應用、H5、 React-Native 等)運行的代碼。

Taro 的源碼我沒看過,但是我看裡面用了很多他們自己寫的babel 包,應該是JIT 模式,加入了中間層,把你寫的東西,編譯成了小程序可以執行的代碼,個人認為小程序不要做得太複雜,不然你還不如做個APP,輕量跨平台,自然是最快速的,而且可以使用TSX 語法,React,太好了。

推薦指數:五顆星

Cordova

它是一個比較古老的技術,但是我目前的公司使用得比較 6,還做成了一套產業體系,我覺得它也挺不錯的。

它是比較傳統的跨平台技術,類似小程序,在 webView 中渲染,原理如下:

其實就是原生的 webView 去加載,執行 H5 代碼,這樣可以跨平台,而且可以隨時更新發佈內容​​。這就是傳統的 hybrid APP (混合開發)。

還有一種 webApp, 直接用 h5 的技術打包成 APP,比較簡單,這個百度下就知道了。

Hybrid 技術應該比較多,但是原理大同小異,都是通過 webView 加載,性能體驗肯定沒有原生好,因為調用 webView 需要幾百毫秒的時間,但是也可以通過一些技術優化,跟誰寫也有很大關係。

快應用

就是華為、小米等國內廠商為了跟小程序競爭搞出來的,像RN 這些框架,回內置一些渲染/ 排版引擎,那麼打包出來提交比較大,快應用是集成到安卓手機的ROM 中,所以只有源碼那部分,安裝體積比較小,這樣就叫快應用。

快應用使用原生 js 開發,框架跟原生微信小程序很像(寫著不舒服,Taro 支持快應用)。

提示:寫快應用的工資很高,感覺基本都在 30K 以上(可能是錯覺)。

Flutter

Flutter 是 Google 推出並開源的移動應用開發框架,主要特點是跨平台、高保真、有些性能。開發者可以通過 Dart 語言開發 APP,一套代碼可以同時運行在 iOS 和 Android 平台以上。 Flutter 提供了豐富的組件、接口,開發者可以很快地為 Flutter 添加 Native 擴展。

同時 Flutter 還可以使用 Native 引擎渲染視圖,這無疑能為用戶提供良好的體驗。

跨平台自繪引擎

Flutter 與用於構建移動應用程序的其他大多數框架不同,因為 Flutter 既不使用 Webview,也不使用操作系統的原生控件。相反, Flutter 使用自己的高性能渲染引擎來繪製 Widget。這樣不僅可以保證在 Android 和 iOS 上 UI 的一致性,而且可以避免因對原生控。

件依賴而帶來的限制及高昂的維護成本。

Flutter 使用ska 作為其2D 渲染引擎,Skia 是Google 的一個2D 圖形處理函數庫,包含字形、坐標轉換,以及點陣圖,且都有高效能且簡潔的表現,Skia 是跨平台的,並且其還提供了非常友好的API,目前Google Chrome 瀏覽器和Android 均採用Skia 作為其繪圖引擎。目前, Flutter 默認支持 iOS、 Android、 Fuchsia( Google 新的自研操作系統) 三個移動平台。但 Flutter 亦可支持 Web 開發 ( Flutter for Web) 和 PC 開發。

高性能

Flutter 的高性能主要靠兩點來保證,首先, Flutter APP 採用 Dart 語言開發。 Dart 在 JT(即時編譯) 模式下,速度與 Javascript 基本持平。同時 Dart 還支持 AOT,當以 AOT 模式運行時, Javascript 便遠遠追不上了。速度的提升對高幀率下的視圖數據計算很有幫助。其次, Flutter 1 使用自己的渲染引擎來繪製 UI,佈局數據等由 Dan 語言直接控制,所以在佈局過程中不需要像 RN 那樣要在 Javascript 和 Native 之間通信。

這一點在一些滑動和拖動的場景下具有明顯的優勢,因為滑動和拖動的過程往往會引起佈局發生變化,所以Javascript 需要與Native 不停地同步佈局信息,這與在瀏覽器中要Javascript頻繁操作DOM 所帶來的問題是相同的,都會帶來比較可觀的性能開銷。

重點:Flutter 自己有自己的渲染引擎,這樣避免了以上幾種跨平台技術的通過中間層通信帶來的性能開銷,但是依然避免不了寫原生代碼,而且目前GitHub 上的issue 還比較多,不過小編已經入坑了,就學最後一個,以後就不學前端了。

Dart 語言學習也需要一些成本,如果公司有這個安排的話,可以入坑嘗試。

綜上五種所述:不一樣的業務場景有一樣的技術場景,技術為產品服務,跨平台的出現並不是為了乾掉原生,而是為了更好的、更高效的開發。