5000字解析:前端五種跨平臺技術
寫在開頭:
本文不涉及到任何代碼,只講概念層面的,結合本人在實際開發(fā)過程中的各種體驗,對這幾種跨平臺技術進行一個點評。
跨平臺技術的由來:
傳統(tǒng)的純原生開發(fā)已經不能滿足日益增長的業(yè)務需求。主要表現(xiàn)在如下兩個方面。
- 動態(tài)化內容需求增大。當需求發(fā)生變化時,純原生應用需要通過版本升級來更新內容,但應用上架、審核是需要周期的,這個周期對高速變化的互聯(lián)網(wǎng)時代來說是很難接受的,所以,對應用動態(tài)化(不發(fā)版也可以更新應用內容)的需求就變得迫在眉睫了。
- 業(yè)務需求變化快,開發(fā)成本變大。由于原生開發(fā)一般都要維護 Android、iOS兩個
開發(fā)團隊,版本迭代時,無論人力成本還是測試成本都會變大。
總結一下,純原生開發(fā)主要面臨動態(tài)化和開發(fā)成本兩個問題,而針對這兩個問題,又誕生了一些跨平臺的動態(tài)化框架。
跨平臺技術簡介
針對原生開發(fā)面臨的問題,人們一直都在努力尋找好的解決方案,然而時至今日,已經存在很多跨平臺框架(注意,本書中所指的“跨平臺”若無特殊說明,即特指 Android和iOS兩個平臺),根據(jù)其原理,主要可分為如下三類。
- H5(HTML5)+原生( Cordova、 Tonic、微信小程序)。
- Javascript開發(fā)+原生渲染( React Native、Wex、快應用)。
- 自繪U+原生( QT Mobile、 Flutter)。
接下來,我們將逐個來了解這三類框架的原理及優(yōu)缺點。
1.12 Hybrid技術簡介
H5+原生混合開發(fā)
這類框架的主要原理是將APP需要動態(tài)變動的一部分內容通過H5來實現(xiàn),通過原生的網(wǎng)頁加載控件 Webview( Android)或 WK Webview(iOS)來加載(以后若無特殊說明,本書將用 Webview來統(tǒng)一指代 Android和iOs中的網(wǎng)頁加載控件)。這樣,H5部分就可以
隨時改變而不用發(fā)版,動態(tài)化需求得到滿足;同時,由于H5代碼只需要一次開發(fā),就能同時在 Android和OS兩個平臺上正常運行,這也可以降低開發(fā)成本,也就是說,H5部分的
功能越多,開發(fā)成本就越小。我們稱這種H5+原生的開發(fā)模式為混合開發(fā),對于采用混合模式開發(fā)的APP,我們稱之為混合應用或 Hybrid APP,如果一個應用的大多數(shù)功能都是采用H5實現(xiàn)的話,我們稱其為 Web APP。
目前混合開發(fā)框架的典型代表有 Cordova、 lonic和微信小程序,值得一提的是,微信小程序目前是在 Webview中渲染的。并非原生渲染,但將來有可能會采用原生渲染。
混合開發(fā)技術點
如之前所述,原生開發(fā)可以訪間平臺的所有功能,而在混合開發(fā)中,H5代碼是運行在
Web Vicw中的, Webview實質上就是一個瀏覽器器內核、其script依然運行在一個權限
受限的沙箱中,所以對大多數(shù)系統(tǒng)能力都沒有訪向權限、如無法訪向文件系統(tǒng)、不能使用藍牙等,所以,對于H5不能實現(xiàn)的功能,都需要原生來實現(xiàn)。
而混合框架一般都會在原生代碼中預先實現(xiàn)一些訪問系統(tǒng)能力的API,然后暴露給 Webview以供 Javascript調用,這樣一來, Webview就成為 Javascript與原生AP之間通信的橋梁,主要負責 Javascript與原生之間調用消息的傳遞,而消息的傳遞必須遵守一個標準的協(xié)議,其規(guī)定了消息的格式與含義,我們將依賴于 Webview的、用于在 Javascript與原生之間通信并實現(xiàn)了某種消息傳輸協(xié)議的工具稱為 Webview Javascript Bridge,簡稱 Jsbridge,它也是混合開發(fā)框架的核心.
我所使用的跨平臺技術:
- Electron
- React-Native
- Taro
- Cordova
- 快應用
- Flutter(剛學習)
- ...
排名由前往后,除了Flutter沒有使用過在商業(yè)項目中
Electron的核心:
Electron就是把Node.js的運行環(huán)境和谷歌瀏覽器內核一起打包了,于是就擁有了Node.js和H5技術的融合能力,又因為是基于C++編寫,于是可以跨平臺。Mac、windows、Linux。
工具類的軟件是最復雜的,例如vscode、word這些,都是極度復雜的,又因為可以調用addon、各種腳本插件,原生第三方插件,這個技術簡直就是黑科技,至今我也不敢說對它熟悉。但是APP Store已經不能上線Electron應用了,而且打包簽名服務器也經常掛
特別注意:Electron開發(fā)出來的東西是軟件,是一個安裝在電腦上的軟件!
我的GitHub可能有你想要的Demo內容:https://github.com/JinJieTan
要想開發(fā)好Electron,要擁有一名C++人員專門編寫插件,一位后端出生的人生操作sqlite數(shù)據(jù)庫(數(shù)據(jù)庫升級雖然可以兼容老版本,但是復雜的應用設計得不好數(shù)據(jù)庫就完了),一位前后端都懂并且熟悉調用操作系統(tǒng)插件的全棧工程師開發(fā),這樣才能hold得住復雜應用。如果你說這樣是不是太浪費了,那我覺得你沒有開發(fā)過復雜的軟件,一個好的軟件(客戶端),要考慮程序反編譯(保護)、奔潰守護進程等異常搜集、用戶自動升級(差量or全量)、本地數(shù)據(jù)庫加密、通信、激活喚醒。。。。太多了,但是大部分前端做的就是后臺管理系統(tǒng),這也是一個悲劇。。。面試造火箭
像以前我就做過將微信和QQ里面一些插件拿出來經過一些處理用在項目里,至此打開了新世界,總之Electron非??简灱夹g,是晉升偽全棧工程師最快的路徑
推薦學習指數(shù):五顆星
React-native
去年愛彼迎把APP的技術從RN換回了原生,首先它是外企,它可能某種程度上,使用RN會比國內有更大的優(yōu)勢,獲得更大的支持。就像你使用Taro,那么你有可能在論壇上找到它的負責人,提出想要的支持,最后它真的支持了(這個是存在的,如果你想認識可以幫你聯(lián)系,我也在建議身邊人使用Taro)
回到正題:
難道RN死了嗎?
JQuery都沒死,它會死嗎?當然不會!RN的生態(tài)非常強大,它開發(fā)出來的,也是真正的原生應用,它的原理如下:
在React-native文件中編寫的代碼,會在內存中生成虛擬DOM對象(其實就是一個JS對象),然后再通過javaScriptCore(IOS自帶,安卓不是,所以RN打包后安卓的包比蘋果大)映射成原生控件樹。很多jsBridge都是基于javaScriptCore實現(xiàn)的
例如:
- iOS代碼發(fā)送通知:
- //需要包含的頭文件
- #import <React/RCTEventDispatcher.h>
- #import <React/RCTBridge.h>
- [self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
- body:@{@"name": @"nnnnnnn"}];
- RN代碼接收通知:
- //創(chuàng)建一個監(jiān)聽收到的通知,需要組件NativeAppEventEmitter
- var listener = NativeAppEventEmitter.addListener(
- 'EventNotification', //監(jiān)聽的通知名稱
- (reminder) => console.log(reminder.name, '收到的通知')
- );
提示:跨平臺不是什么高深的技術,只要搞懂它的運行機制原理,就好開發(fā),定位問題。
那么RN有什么缺點呢?例如頻繁setState,可能會造成卡頓(做動畫的時候容易掉幀,特別是性能差的手機),但是也是可以使用一些技術優(yōu)化盡量避免,跟是誰寫的有很大關系,還有就是項目變得特別大,跟原生交互特別多,特別復雜的應用,跨平臺遇到的問題兼容處理也會越來越多,這也是為什么愛彼迎會換回原生的原因,維護確實比較麻煩,還有版本環(huán)境的問題,有可能你升級了以后再也啟動不了了。。。
推薦理由:開發(fā)快速,生態(tài)成熟,使用React的JSX語法和FLex布局快速開發(fā)原生應用,推薦學習指數(shù):四顆星
Taro
小程序跨平臺開發(fā),一款可以用TSX、JSX和React語法開發(fā)小程序的框架,內置了一些UI組件,還有物料市場,目前看勢頭很好。還可以集成React-native,真正做到一套代碼多處運行,不僅能編譯成各種平臺小程序,還可以是RN的應用~ 666 ,還支持快應用
https://taro.aotu.io/
現(xiàn)如今市面上端的形態(tài)多種多樣,Web、React-Native、微信小程序等各種端大行其道,當業(yè)務要求同時在不同的端都要求有所表現(xiàn)的時候,針對不同的端去編寫多套代碼的成本顯然非常高,這時候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。
使用 Taro,我們可以只書寫一套代碼,再通過 Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/百度/支付寶/字節(jié)跳動/QQ/京東小程序、快應用、H5、React-Native 等)運行的代碼。
Taro的源碼我沒看過,但是我看里面用了很多他們自己寫的babel包,應該是JIT模式,加入了中間層,把你寫的東西,編譯成了小程序可以執(zhí)行的代碼,個人認為小程序不要做得太復雜,不然你還不如做個APP,輕量跨平臺,自然是最快速的,而且可以使用TSX語法,React,太好了。
推薦指數(shù):五顆星
Cordova
它是一個比較古老的技術,但是我目前的公司使用得比較6,還做成了一套產業(yè)體系,我覺得它也挺不錯的
它是比較傳統(tǒng)的跨平臺技術,類似小程序,在webView中渲染,原理如下:
其實就是原生的webView去加載,執(zhí)行H5代碼,這樣可以跨平臺,而且可以隨時更新發(fā)布內容。這就是傳統(tǒng)的hybrid APP (混合開發(fā))
還有一種webApp,直接用h5的技術打包成APP,比較簡單,這個百度下就知道了
Hybrid技術應該比較多,但是原理大同小異,都是通過webView加載,性能體驗肯定沒有原生好,因為調用webView需要幾百毫秒的時間,但是也可以通過一些技術優(yōu)化,跟誰寫也有很大關系
快應用
就是華為、小米等國內廠商為了跟小程序競爭搞出來的,像RN這些框架,回內置一些渲染/排版引擎,那么打包出來提交比較大,快應用是集成到安卓手機的ROM中,所以只有源碼那部分,安裝體積比較小,這樣就叫快應用
快應用使用原生js開發(fā),框架跟原生微信小程序很像(寫著不舒服,Taro支持快應用)
提示:寫快應用的工資很高,感覺基本都在30K以上(可能是錯覺)
Flutter
Flutter是ogle推出并開源的移動應用開發(fā)框架,主要特點是跨平臺、高保真、有些性能。開發(fā)者可以通過Dar語言開發(fā)APP,一套代碼可以同時運行在OS和 Android平臺以上。Flutter提供了豐富的組件、接口,開發(fā)者可以很快地為 Flutter添加 Native擴展。
同時Flutter還可以使用 Native引擎渲染視圖,這無疑能為用戶提供良好的體驗。
跨平臺自繪引擎
Flutter與用于構建移動應用程序的其他大多數(shù)框架不同,因為 Flutter既不使用Webview,也不使用操作系統(tǒng)的原生控件。相反, Flutter使用自己的高性能渲染引擎來繪制 Widget。這樣不僅可以保證在 Android和iOS上UI的一致性,而且可以避免因對原生控
件依賴而帶來的限制及高昂的維護成本。
Flutter使用ska作為其2D渲染引擎,Skia是 Google的一個2D圖形處理函數(shù)庫,包含字形、坐標轉換,以及點陣圖,且都有高效能且簡潔的表現(xiàn),Skia是跨平臺的,并且其還提供了非常友好的API,目前 Google Chrome瀏覽器和 Android均采用Skia作為其繪圖引擎。目前, Flutter默認支持iOS、 Android、 Fuchsia( Google新的自研操作系統(tǒng))三個移動平臺。但 Flutter亦可支持Web開發(fā)( Flutter for Web)和PC開發(fā)
高性能
Flutter的高性能主要靠兩點來保證,首先, Flutter APP采用Dart語言開發(fā)。Dart在JT(即時編譯)模式下,速度與 Javascript基本持平。同時Dar還支持AOT,當以AOT模式運行時, Javascript便遠遠追不上了。速度的提升對高幀率下的視圖數(shù)據(jù)計算很有幫助。其次, Flutter 1使用自己的渲染引擎來繪制UI,布局數(shù)據(jù)等由Dan語言直接控制,所以在布局過程中不需要像RN那樣要在 Javascript和 Native之間通信。
這一點在一些滑動和拖動的場景下具有明顯的優(yōu)勢,因為滑動和拖動的過程往往會引起布局發(fā)生變化,所以 Javascript需要與 Native不停地同步布局信息,這與在瀏覽器中要 Javascript頻繁操作DOM所帶來的問題是相同的,都會帶來比較可觀的性能開銷。
重點:Flutter自己有自己的渲染引擎,這樣避免了以上幾種跨平臺技術的通過中間層通信帶來的性能開銷,但是依然避免不了寫原生代碼,而且目前GitHub上的issue還比較多,不過小編已經入坑了,就學最后一個,以后就不學前端了
Dart語言學習也需要一些成本,如果公司有這個安排的話,可以入坑嘗試
綜上五種所述:不一樣的業(yè)務場景有一樣的技術場景,技術為產品服務,跨平臺的出現(xiàn)并不是為了干掉原生,而是為了更好的、更高效的開發(fā)。