標(biāo)簽(空格分隔): 移動應(yīng)用 跨平臺 混和開發(fā) Flutter
移動應(yīng)用跨平臺開發(fā)框架郑临,根據(jù)其原理颜骤,主要分為三類:
- 混合開發(fā)聂渊,即H5+原生(Cordova、Ionic穷躁、微信小程序)
- JavaScript開發(fā)+原生渲染 (React Native耕肩、Weex、快應(yīng)用)
- 自繪UI+原生(QT for mobile、Flutter)
Hybrid技術(shù)
H5+原生混合開發(fā)
這類框架主要原理就是將APP的一部分需要動態(tài)變動的內(nèi)容通過H5來實現(xiàn)猿诸,通過原生的網(wǎng)頁加載控件WebView (Android)或WKWebView(ios)來加載(以后若無特殊說明婚被,用WebView來統(tǒng)一指代android和ios中的網(wǎng)頁加載控件)。這樣一來梳虽,H5部分是可以隨時改變而不用發(fā)版址芯,動態(tài)化需求能滿足;同時窜觉,由于h5代碼只需要一次開發(fā)谷炸,就能同時在Android和iOS兩個平臺運行,這也可以減小開發(fā)成本竖螃,也就是說淑廊,h5部分功能越多逗余,開發(fā)成本就越小特咆。我們稱這種h5+原生的開發(fā)模式為混合開發(fā) ,采用混合模式開發(fā)的APP我們稱之為混合應(yīng)用或Hybrid APP 录粱,如果一個應(yīng)用的大多數(shù)功能都是H5實現(xiàn)的話腻格,我們稱其為Web APP 。
目前混合開發(fā)框架的典型代表有:Cordova啥繁、Ionic 和微信小程序菜职,值得一提的是微信小程序目前是在webview中渲染的,并非原生渲染旗闽,但將來有可能會采用原生渲染酬核。
混合開發(fā)技術(shù)點
原生開發(fā)可以訪問平臺所有功能,而混合開發(fā)中适室,h5代碼是運行在WebView中嫡意,而WebView實質(zhì)上就是一個瀏覽器內(nèi)核,其JavaScript依然運行在一個權(quán)限受限的沙箱中捣辆,所以對于大多數(shù)系統(tǒng)能力都沒有訪問權(quán)限蔬螟,如無法訪問文件系統(tǒng)、不能使用藍牙等汽畴。所以旧巾,對于H5不能實現(xiàn)的功能,都需要原生去做忍些。而混合框架一般都會在原生代碼中預(yù)先實現(xiàn)一些訪問系統(tǒng)能力的API鲁猩, 然后暴露給WebView以供JavaScript調(diào)用,這樣一來罢坝,WebView就成為了JavaScript與原生API之間通信的橋梁绳匀,主要負(fù)責(zé)JavaScript與原生之間傳遞調(diào)用消息,而消息的傳遞必須遵守一個標(biāo)準(zhǔn)的協(xié)議,它規(guī)定了消息的格式與含義疾棵,我們把依賴于WebView的用于在JavaScript與原生之間通信并實現(xiàn)了某種消息傳輸協(xié)議的工具稱之為WebView JavaScript Bridge, 簡稱 JsBridge戈钢,它也是混合開發(fā)框架的核心。
總結(jié)
混合應(yīng)用的優(yōu)點是動態(tài)內(nèi)容是H5是尔,web技術(shù)棧殉了,社區(qū)及資源豐富,缺點是性能不好拟枚,對于復(fù)雜用戶界面或動畫薪铜,webview不堪重任。
JavaScript開發(fā)+原生渲染
React Native (簡稱RN)是Facebook于2015年4月開源的跨平臺移動應(yīng)用開發(fā)框架恩溅,是Facebook早先開源的JS框架 React 在原生移動應(yīng)用平臺的衍生產(chǎn)物隔箍,目前支持iOS和Android兩個平臺。RN使用Javascript語言脚乡,類似于HTML的JSX蜒滩,以及CSS來開發(fā)移動應(yīng)用,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進入移動應(yīng)用開發(fā)領(lǐng)域奶稠。
由于RN和React原理相通俯艰,并且Flutter也是受React啟發(fā),很多思想也都是相通的锌订,萬丈高樓平地起竹握,我們有必要深入了解一下React原理。React是一個響應(yīng)式的Web框架辆飘,我們先了解一下兩個重要的概念:Dom樹與響應(yīng)式編程啦辐。
DOM樹與控件樹
文檔對象模型(Document Object Model,簡稱DOM)蜈项,是W3C組織推薦的處理可擴展標(biāo)志語言的標(biāo)準(zhǔn)編程接口芹关,一種獨立于平臺和語言的方式訪問和修改一個文檔的內(nèi)容和結(jié)構(gòu)。換句話說战得,這是表示和處理一個HTML或XML文檔的標(biāo)準(zhǔn)接口充边。簡單來說,DOM就是文檔樹常侦,與用戶界面控件樹對應(yīng)浇冰,在前端開發(fā)中通常指HTML對應(yīng)的渲染樹,但廣義的DOM也可以指Android中的XML布局文件對應(yīng)的控件樹聋亡,而術(shù)語DOM操作就是指直接來操作渲染樹(或控件樹)肘习, 因此,可以看到其實DOM樹和控件樹是等價的概念坡倔,只不過前者常用語Web開發(fā)中漂佩,而后者常用于原生開發(fā)中脖含。
響應(yīng)式編程
React中提出一個重要思想:狀態(tài)改變則UI隨之自動改變,而React框架本身就是響應(yīng)用戶狀態(tài)改變的事件而執(zhí)行重新構(gòu)建用戶界面的工作投蝉,這就是典型的響應(yīng)式編程范式养葵,下面我們總結(jié)一下React中響應(yīng)式原理:
開發(fā)者只需關(guān)注狀態(tài)轉(zhuǎn)移(數(shù)據(jù)),當(dāng)狀態(tài)發(fā)生變化瘩缆,React框架會自動根據(jù)新的狀態(tài)重新構(gòu)建UI关拒。
React框架在接收到用戶狀態(tài)改變通知后,會根據(jù)當(dāng)前渲染樹庸娱,結(jié)合最新的狀態(tài)改變着绊,通過Diff算法,計算出樹中變化的部分熟尉,然后只更新變化的部分(DOM操作)归露,從而避免整棵樹重構(gòu),提高性能斤儿。
值得注意的是剧包,在第二步中,狀態(tài)變化后React框架并不會立即去計算并渲染DOM樹的變化部分雇毫,相反玄捕,React會在DOM的基礎(chǔ)上建立一個抽象層踩蔚,即虛擬DOM樹棚放,對數(shù)據(jù)和狀態(tài)所做的任何改動,都會被自動且高效的同步到虛擬DOM馅闽,最后再批量同步到真實DOM中飘蚯,而不是每次改變都去操作一下DOM。為什么不能每次改變都直接去操作DOM樹福也?這是因為在瀏覽器中每一次DOM操作都有可能引起瀏覽器的重繪或回流:
如果DOM只是外觀風(fēng)格發(fā)生變化局骤,如顏色變化,會導(dǎo)致瀏覽器重繪界面暴凑。
如果DOM樹的結(jié)構(gòu)發(fā)生變化峦甩,如尺寸、布局现喳、節(jié)點隱藏等導(dǎo)致凯傲,瀏覽器就需要回流(及重新排版布局)。
而瀏覽器的重繪和回流都是比較昂貴的操作嗦篱,如果每一次改變都直接對DOM進行操作冰单,這會帶來性能問題,而批量操作只會觸發(fā)一次DOM更新灸促。
思考題:Diff操作和DOM批量更新難道不應(yīng)該是瀏覽器的職責(zé)嗎诫欠?第三方框架中去做合不合適涵卵?
React Native
上文已經(jīng)提到React Native 是React 在原生移動應(yīng)用平臺的衍生產(chǎn)物,那兩者主要的區(qū)別是什么呢荒叼?其實轿偎,主要的區(qū)別在于虛擬DOM映射的對象是什么。React中虛擬DOM最終會映射為瀏覽器DOM樹被廓,而RN中虛擬DOM會通過 JavaScriptCore 映射為原生控件樹贴硫。
JavaScriptCore 是一個JavaScript解釋器,它在React Native中主要有兩個作用:
- 為JavaScript提供運行環(huán)境伊者。
- 是JavaScript與原生應(yīng)用之間通信的橋梁英遭,作用和JsBridge一樣,事實上亦渗,在iOS中挖诸,很多JsBridge的實現(xiàn)都是基于 JavaScriptCore 。
而RN中將虛擬DOM映射為原生控件的過程中分兩步:
- 布局消息傳遞法精; 將虛擬DOM布局信息傳遞給原生多律;
- 原生根據(jù)布局信息通過對應(yīng)的原生控件渲染控件樹;
至此搂蜓,React Native 便實現(xiàn)了跨平臺狼荞。 相對于混合應(yīng)用,由于React Native是原生控件渲染帮碰,所以性能會比混合應(yīng)用中H5好很多相味,同時React Native是Web開發(fā)技術(shù)棧,也只需維護一份代碼殉挽,同樣是跨平臺框架丰涉。
Weex
Weex是阿里巴巴于2016年發(fā)布的跨平臺移動端開發(fā)框架,思想及原理和React Native類似斯碌,最大的不同是語法層面一死,Weex支持Vue語法和Rax語法,Rax 的 DSL 語法是基于 React JSX 語法而創(chuàng)造傻唾。與 React 不同投慈,在 Rax 中 JSX 是必選的,它不支持通過其它方式創(chuàng)建組件冠骄,所以學(xué)習(xí) JSX 是使用 Rax 的必要基礎(chǔ)伪煤。而React Native只支持JSX語法。
快應(yīng)用
快應(yīng)用是華為猴抹、小米带族、OPPO、魅族等國內(nèi)9大主流手機廠商共同制定的輕量級應(yīng)用標(biāo)準(zhǔn)蟀给,目標(biāo)直指微信小程序蝙砌。它也是采用JavaScript語言開發(fā)阳堕,原生控件渲染,與React Native和Weex相比主要有兩點不同:
- 快應(yīng)用自身不支持Vue或React語法择克,其采用原生JavaScript開發(fā)恬总,其開發(fā)框架和微信小程序很像,值得一提的是小程序目前已經(jīng)可以使用Vue語法開發(fā)(mpvue)肚邢,從原理上來講壹堰,Vue的語法也可以移植到快應(yīng)用上。
- React Native和Weex的渲染/排版引擎是集成到框架中的骡湖,每一個APP都需要打包一份贱纠,安裝包體積較大;而快應(yīng)用渲染/排版引擎是集成到ROM中的响蕴,應(yīng)用中無需打包谆焊,安裝包體積小,正因如此浦夷,快應(yīng)用才能在保證性能的同時做到快速分發(fā)廷臼。
總結(jié)
JavaScript開發(fā)+原生渲染的方式主要優(yōu)點如下:
- 采用Web開發(fā)技術(shù)棧携茂,社區(qū)龐大、上手快便贵、開發(fā)成本相對較低牙咏。
- 原生渲染掩驱,性能相比H5提高很多巩掺。
- 動態(tài)化較好,支持熱更新辫继。
不足:
- 渲染時需要JavaScript和原生之間通信怒见,在有些場景如拖動可能會因為通信頻繁導(dǎo)致卡頓俗慈。
- JavaScript為腳本語言姑宽,執(zhí)行時需要JIT,執(zhí)行效率和AOT代碼仍有差距闺阱。
- 由于渲染依賴原生控件炮车,不同平臺的控件需要單獨維護,并且當(dāng)系統(tǒng)更新時酣溃,社區(qū)控件可能會滯后瘦穆;除此之外,其控件系統(tǒng)也會受到原生UI系統(tǒng)限制赊豌,例如扛或,在Android中,手勢沖突消歧規(guī)則是固定的碘饼,這在使用不同人寫的控件嵌套時熙兔,手勢沖突問題將會變得非常棘手悲伶。
QT Moblie與Flutter
在本篇中,我們看看最后一種跨平臺技術(shù):自繪UI+原生住涉。這種技術(shù)的思路是麸锉,通過在不同平臺實現(xiàn)一個統(tǒng)一接口的渲染引擎來繪制UI,而不依賴系統(tǒng)原生控件舆声,所以可以做到不同平臺UI的一致性花沉。注意,自繪引擎解決的是UI的跨平臺問題媳握,如果涉及其它系統(tǒng)能力調(diào)用碱屁,依然要涉及原生開發(fā)。這種平臺技術(shù)的優(yōu)點如下:
- 性能高蛾找;由于自繪引擎是直接調(diào)用系統(tǒng)API來繪制UI忽媒,所以性能和原生控件接近。
- 靈活腋粥、組件庫易維護晦雨、UI外觀保真度和一致性高;由于UI渲染不依賴原生控件隘冲,也就不需要根據(jù)不同平臺的控件單獨維護一套組件庫闹瞧,所以代碼容易維護。由于組件庫是同一套代碼展辞、同一個渲染引擎奥邮,所以在不同平臺,組件顯示外觀可以做到高保真和高一致性罗珍;另外洽腺,由于不依賴原生控件,也就不會受原生布局系統(tǒng)的限制覆旱,這樣布局系統(tǒng)會非常靈活蘸朋。
不足:
- 動態(tài)性不足;為了保證UI繪制性能扣唱,自繪UI系統(tǒng)一般都會采用AOT模式編譯其發(fā)布包藕坯,所以應(yīng)用發(fā)布后,不能像Hybrid和RN那些使用JavaScript(JIT)作為開發(fā)語言的框架那樣動態(tài)下發(fā)代碼噪沙。
Flutter正是實現(xiàn)一套自繪引擎炼彪,并擁有一套自己的UI布局系統(tǒng)。不過正歼,自繪制引擎的思路并不是什么新概念辐马,F(xiàn)lutter并不是第一個嘗試這么做的,在它之前有一個典型的代表局义,即大名鼎鼎的QT喜爷。
QT簡介
Qt是一個1991年由Qt Company開發(fā)的跨平臺C++圖形用戶界面應(yīng)用程序開發(fā)框架膜楷。2008年,Qt Company科技被諾基亞公司收購贞奋,Qt也因此成為諾基亞旗下的編程語言工具赌厅。2012年,Qt被Digia收購轿塔。2014年4月特愿,跨平臺集成開發(fā)環(huán)境Qt Creator 3.1.0正式發(fā)布,實現(xiàn)了對于iOS的完全支持勾缭,新增WinRT揍障、Beautifier等插件,廢棄了無Python接口的GDB調(diào)試支持俩由,集成了基于Clang的C/C++代碼模塊毒嫡,并對Android支持做出了調(diào)整,至此實現(xiàn)了全面支持iOS幻梯、Android兜畸、WP,它提供給應(yīng)用程序開發(fā)者構(gòu)建圖形用戶界面所需的所有功能碘梢。但是咬摇,QT雖然在PC端獲得了巨大成功,備受社區(qū)追捧煞躬,然而其在移動端卻表現(xiàn)不佳肛鹏,在近幾年,雖然偶爾能聽到QT的聲音恩沛,但一直很弱在扰,無論QT本身技術(shù)如何、設(shè)計思想如何雷客,但事實上終究是敗了芒珠,究其原因,筆者認(rèn)為主要有四:
第一:QT移動開發(fā)社區(qū)太小佛纫,學(xué)習(xí)資料不足妓局,生態(tài)不好。
第二:官方推廣不利呈宇,支持不夠。
第三:移動端發(fā)力較晚局雄,市場已被其它動態(tài)化框架占領(lǐng)(Hybrid和RN)甥啄。
第四:在移動開發(fā)中,C++開發(fā)和Web開發(fā)棧相比有著先天的劣勢炬搭,直接結(jié)果就是QT開發(fā)效率太低蜈漓。
基于此四點穆桂,盡管QT是移動端開發(fā)跨平臺自繪引擎的先驅(qū),但卻成為了烈士融虽。
Flutter簡介
Flutter是Google發(fā)布的一個用于創(chuàng)建跨平臺享完、高性能移動應(yīng)用的框架。Flutter和QT mobile一樣有额,都沒有使用原生控件般又,相反都實現(xiàn)了一個自繪引擎,使用自身的布局巍佑、繪制系統(tǒng)茴迁。那么,我們會擔(dān)心萤衰,QT mobile面對的問題Flutter是否也一樣堕义,F(xiàn)lutter會不會步入QT mobile后塵,成為另一個烈士脆栋?要回到這個問題倦卖,我們先來看看Flutter誕生過程:
2017 年 Google I/O 大會上,Google 首次推出了一款新的用于創(chuàng)建跨平臺椿争、高性能的移動應(yīng)用框架——Flutter糖耸。
2018年2月,F(xiàn)lutter發(fā)布了第一個Beta版本丘薛,同年五月嘉竟, 在2018年Google I/O 大會上,F(xiàn)lutter 更新到了 beta 3 版本洋侨。
2018年6月舍扰,F(xiàn)lutter發(fā)布了首個預(yù)覽版本,這意味著 Flutter 進入了正式版(1.0)發(fā)布前的最后階段希坚。
觀其發(fā)展边苹,在2018年5月份,F(xiàn)lutter 進入了 GitHub stars 排行榜前 100 名裁僧,已有 27k star个束。而今天(2018年8月16日),已經(jīng)有35K的Star聊疲。經(jīng)歷了短短一年多的時間茬底,F(xiàn)lutter 生態(tài)系統(tǒng)得以快速增長,由此可見获洲,F(xiàn)lutter在開發(fā)者中受到了熱烈的歡迎阱表,其未來發(fā)展值得期待!
現(xiàn)在,我們來和QT mobile做一個對比:
生態(tài)最爬;從Github上來看涉馁,目前Flutter活躍用戶正在高速增長。從Stackoverflow上提問來看爱致,F(xiàn)lutter社區(qū)現(xiàn)在已經(jīng)很龐大烤送。Flutter的文檔、資源也越來越豐富糠悯,開發(fā)過程中遇到的很多問題都可以在Stackoverflow或其github issue中找到答案帮坚。
技術(shù)支持;現(xiàn)在Google正在大力推廣Flutter逢防,F(xiàn)lutter的作者中很多人都是來自Chromium團隊叶沛,并且github上活躍度很高。另一個角度忘朝,從今年上半年Flutter頻繁的版本發(fā)布也可以看出Google對Flutter的投入的資源不小灰署,所以在官方技術(shù)支持這方面,大可不必?fù)?dān)心局嘁。
開發(fā)效率溉箕;Flutter的熱重載可幫助開發(fā)者快速地進行測試、構(gòu)建UI悦昵、添加功能并更快地修復(fù)錯誤肴茄。在iOS和Android模擬器或真機上可以實現(xiàn)毫秒級熱重載,并且不會丟失狀態(tài)但指。這真的很棒寡痰,相信我,如果你是一名原生開發(fā)者棋凳,體驗了Flutter開發(fā)流后拦坠,很可能就不想重新回去做原生了,畢竟很少有人不吐槽原生開發(fā)的編譯速度剩岳。
基于以上三點贞滨,相信讀者和筆者一樣,flutter未來如何拍棕,心中自有定論晓铆。
本章總結(jié)
目前移動開發(fā)中三種跨平臺技術(shù)對比:
上表中開發(fā)語言主要指UI的開發(fā)語言,動態(tài)化主要指是否支持動態(tài)下發(fā)代碼和是否支持熱更新绰播。值得注意的是Flutter的Release包默認(rèn)是使用Dart AOT模式編譯的骄噪,所以不支持動態(tài)化,但Dart還有JIT或snapshot運行方式幅垮,這些模式都是支持動態(tài)化的腰池,后續(xù)會介紹
整理自https://book.flutterchina.club/chapter1/mobile_development_intro.html