移動(dòng)端跨平臺(tái)技術(shù)之下的變與不變
一、跨平臺(tái),是想跨哪些平臺(tái)?
目前來看,移動(dòng)端跨平臺(tái)需求主要集中在:
- 跨 PC 端與移動(dòng)端:PC 向無線過渡的早期,希望 PC Web 與移動(dòng) Web 復(fù)用同一套代碼
- 跨 Native 與 Web:商品詳情頁等要求有一套功能差不多的 Web 頁能夠在端外訪問,需要跨 Native App 與 Web
- 跨 Native 雙端:出于開發(fā)效率等原因,希望 Android、iOS 雙端復(fù)用一套業(yè)務(wù)代碼
- 跨 App:一些產(chǎn)品功能期望能在多個(gè)渠道投放上線,以工具類需求為主,如打車、買票、點(diǎn)餐
在可預(yù)見的未來,可能還會(huì)有這些跨平臺(tái)需求:
- 跨輕應(yīng)用:系統(tǒng)級(jí)即用即走的輕量級(jí)應(yīng)用,如Android 快應(yīng)用、iOS App Clips
- 跨 IoT 設(shè)備:各種有顯示屏的設(shè)備都會(huì)成為新的“端”,如車載設(shè)備、智能家居
- 跨一切客戶端:可能是偽需求,同一產(chǎn)品在不同平臺(tái)的側(cè)重點(diǎn)不同,或許并不需要把所有功能完整地搬到各式各樣的客戶端設(shè)備/平臺(tái)渠道上,例如快應(yīng)用與 Native App 的定位顯然不一樣
在這樣的時(shí)代背景下,無論從資源成本、開發(fā)效率,還是從產(chǎn)品迭代、技術(shù)演進(jìn)的角度來看,跨平臺(tái)開發(fā)都是強(qiáng)需求,所以才有了層出不窮的各種跨平臺(tái)方案探索
二、層出不窮的跨平臺(tái)技術(shù)
細(xì)數(shù)近幾年業(yè)界主流的移動(dòng)端跨平臺(tái)方案,可大致分為 3 類:
- Web 生而跨平臺(tái):只要有瀏覽器或 WebView,依托 Web 技術(shù)即可輕松跨平臺(tái),如 Web App、PWA(Progressive Web Apps)、Hybrid App、PHA(Progress Hybrid App)
- 容器化 Native 跨端:將 Native App 改造成標(biāo)準(zhǔn)化的容器,進(jìn)而允許一套代碼跨多端標(biāo)準(zhǔn)容器運(yùn)行,如 React Native/Weex、Flutter
- 小程序一碼多投跨 App:國內(nèi)市場中,越來越多的超級(jí) App 支持了小程序,但各自的小程序框架并沒有統(tǒng)一標(biāo)準(zhǔn),于是有了Taro、kbone、uni-app等一系列跨小程序框架的方案來滿足跨 App 投放產(chǎn)品功能的需求
跨平臺(tái):Web 與生俱來
跨平臺(tái)是 Web 與生俱來的優(yōu)勢,瀏覽器和 WebView 都是 W3C 規(guī)范下的標(biāo)準(zhǔn)化 Web 容器,因此 Web 頁面能夠輕松投放到端外瀏覽器、端內(nèi) WebView、以及其它 App 提供的 WebView 中
單從成本角度來看,Web 方案是跨平臺(tái)的不二之選:
- 沒有額外的學(xué)習(xí)成本:一套基礎(chǔ)技術(shù)吃遍端內(nèi)、端外、甚至 PC 瀏覽器、電視機(jī)頂盒
- 不依賴特殊的配套設(shè)施:開發(fā)、調(diào)試、構(gòu)建、發(fā)布、監(jiān)控、運(yùn)維等所有工程化環(huán)節(jié)都是通用的
- 坐擁龐大的既有生態(tài):npm 百萬模塊,應(yīng)有盡有
- Web 基于開放標(biāo)準(zhǔn):走出去引進(jìn)來都不是難事
并且,Web 本身就是一個(gè)平臺(tái),退可守,技術(shù)風(fēng)險(xiǎn)更低
但在另一些方面,依靠 Web 技術(shù)跨端也存在其局限性:
- 平臺(tái)能力:受限于 Web 標(biāo)準(zhǔn)容器,無法滿足平臺(tái)能力相關(guān)的需求,如相機(jī)、藍(lán)牙、多媒體等
- 體驗(yàn):移動(dòng)端 Web 體驗(yàn)遠(yuǎn)不及 Native,主要體現(xiàn)在首屏加載慢、動(dòng)畫卡頓、長頁滾動(dòng)閃爍等場景
- 性能:內(nèi)存消耗大、GPU 利用率低
加上 Web 標(biāo)準(zhǔn)更迭慢,新特性兼容性差(如Push API過去許多年了,仍然無法放心使用),Web 基礎(chǔ)能力難以滿足 Native 端的需求。因此,在傳統(tǒng) Web App 的基礎(chǔ)上,展開了更多的探索:
- PWA(Progressive Web Apps):離線緩存、系統(tǒng)通知、主屏圖標(biāo)等類 Native App 能力加持之下的 Web App,但兼容性并不樂觀
- Hybrid App:Web 與 Native 混合的方案,將由 Native 實(shí)現(xiàn)的平臺(tái)能力(比如掃描二維碼)注入到 WebView 環(huán)境供 Web App 使用,以擴(kuò)展 Web 的平臺(tái)能力
- PHA(Progressive Hybrid App):PWA 與 Hybrid 思想的結(jié)合,通過 Hybrid 手段讓 Web 的性能和體驗(yàn)接近 Native
PWA 標(biāo)準(zhǔn)化似乎走不通,即便走通了能夠真正放心用起來可能也是數(shù)年之后了。Hybrid App 解決了一部分問題(平臺(tái)能力擴(kuò)展),但還不夠。PHA 是這兩種思路的延續(xù),借助 Native 技術(shù)實(shí)現(xiàn) PWA 的夢(mèng)想
但無論 PHA 還是 HA,引入 Native 依賴都意味著 Web 開放性的損失,繼而帶來跨端、跨 App 方面的問題
跨端:容器化 Native
除 Web 天然跨端之外,另一種統(tǒng)一多端的思路是將 Native 定制成標(biāo)準(zhǔn)容器,讓同一份代碼跑在一個(gè)個(gè)標(biāo)準(zhǔn)容器中,例如:
- Android 容器:Native 殼 App
- iOS 容器:Native 殼 App
- Web 容器:Web Runtime
- React Native 跨 Android、iOS、Web、Windows 四端,Weex 跨 Android、iOS、Web 三端,F(xiàn)lutter 以類似的方式跨 Android、iOS、Web、Linux 四端
從技術(shù)角度來看,RN 與 Weex 在 Native 容器中提供了 JavaScript 運(yùn)行環(huán)境,以及布局引擎,渲染層都采用 Native 控件,因此 UI 交互上仍然存在系統(tǒng)差異。而 Flutter 方案更徹底一些,連渲染層也換成了基于圖形引擎自繪 UI 控件,從而保證 UI 交互的跨端一致性
然而,由于容器化 Native 的方案是從 Native 出發(fā),沒有跨端天賦,除了要想辦法支持 Web,還面臨一個(gè)更難解決的問題——跨 App
跨 App:小程序一碼多投

技術(shù)視角下,小程序跨 Native App 仍然是依靠 Web 方案,那么,為什么不直接用 Web App 呢?
由于商業(yè)競爭等因素,闖入別人家地盤的 Web App 通常會(huì)遭到一些限制,如安全警告、權(quán)限控制、甚至干脆禁止訪問(所以才有了口令分享等彎彎繞繞的方式)
小程序則不同,其初衷是開放的,歡迎大家入駐(當(dāng)然,也要遵守規(guī)則),并且國內(nèi)的許多大型 App 也都相繼開放了小程序能力,小程序逐漸成為跨 App 的正規(guī)方式。但小程序平臺(tái)多起來之后,框架標(biāo)準(zhǔn)不統(tǒng)一的問題也暴露了出來,都叫小程序,但都大同小異,于是,如何快速產(chǎn)出多種小程序變成了一個(gè)值得探索的技術(shù)課題
實(shí)現(xiàn)原理上分為兩種,編譯轉(zhuǎn)換與運(yùn)行時(shí)適配,前者能夠達(dá)到等同于原生小程序的性能但帶來了諸多限制(編譯器難以識(shí)別的寫法都不支持),現(xiàn)有的 Web App 不那么容易遷移成跨 App 小程序,例如 Taro、uni-app 等。后者犧牲性能換取了更多的可能性,現(xiàn)有的 Web App 能夠相對(duì)容易地遷移過來,例如 Taro Next、kbone 等
P.S.當(dāng)然,也可以有動(dòng)靜結(jié)合的思路,理想情況下,絕大多數(shù)基礎(chǔ)業(yè)務(wù)走運(yùn)行時(shí)平遷,個(gè)別高性能要求的部分走編譯轉(zhuǎn)換
三、重重變化之中,什么才是不變量?
渠道/端/平臺(tái)、業(yè)務(wù)代碼、工程化配套設(shè)施似乎都在快速地發(fā)生變化,沒有哪個(gè)是穩(wěn)定不變的
既然全都在變,就換個(gè)角度看,哪個(gè)部分一定會(huì)發(fā)生變化?
- 容器:新的渠道/端/平臺(tái)都是新的容器
- 跨容器技術(shù):新容器的出現(xiàn),意味著新的跨容器技術(shù)要求
哪個(gè)部分是不必要跟著變的?
- 業(yè)務(wù)代碼:技術(shù)方案的更迭、新渠道/端/平臺(tái)的出現(xiàn),通常伴隨著業(yè)務(wù)代碼的遷移,Native 切 React Native 切 Flutter……樂此不疲,但從成本上看,業(yè)務(wù)代碼并不一定也并不應(yīng)該跟著變
- 工程化配套設(shè)施:大多與技術(shù)棧強(qiáng)相關(guān),例如 Web App 的開發(fā)、調(diào)試、構(gòu)建、發(fā)布、監(jiān)控、運(yùn)維與 Native App 存在諸多差異,但其中更基礎(chǔ)的部分是技術(shù)無關(guān),而流程相關(guān)的,例如構(gòu)建-發(fā)布流程、監(jiān)控運(yùn)維服務(wù)等并不需要跟著變
- 容器中的平臺(tái)能力:無論何種跨容器的方案,平臺(tái)能力擴(kuò)展需求都是一致的,對(duì)應(yīng)的 Native 模塊封裝不應(yīng)該跟著變
業(yè)務(wù)代碼遷移的成本是非常高的(涉及技術(shù)棧變化時(shí)更痛),配套設(shè)施的推倒重建也絕對(duì)是大工程,那么,有沒有辦法把這些不應(yīng)該跟著變的部分固定下來?
有,將變化的部分抽象出去。依賴抽象而不依賴具體,上層就不用跟著變了:
- 標(biāo)準(zhǔn)框架 \
- --------- | 配套設(shè)施
- 標(biāo)準(zhǔn)容器 /
在這樣的抽象模型下,上層業(yè)務(wù)代碼依賴標(biāo)準(zhǔn)業(yè)務(wù)框架,而不直接依賴容器能力,從而允許業(yè)務(wù)框架以下的部分能夠替換。業(yè)務(wù)框架依賴抽象的標(biāo)準(zhǔn)容器,而不與具體的特定容器相綁定,可替換為遵循容器標(biāo)準(zhǔn)的其它容器
基于標(biāo)準(zhǔn)框架,能夠提供配套的腳手架、組件庫、可視化搭建等配套開發(fā)工具?;跇?biāo)準(zhǔn)容器,能夠建立性能診斷、事件追蹤等配套調(diào)試能力,從而覆蓋到工程化的整個(gè)鏈路,配套設(shè)施也幾乎不用跟著變了
至于平臺(tái)能力擴(kuò)展,作為標(biāo)準(zhǔn)容器中的重要部分,也應(yīng)該抽象出標(biāo)準(zhǔn) API(類比瀏覽器提供的 BOM 系 API),供上層業(yè)務(wù)使用
四、跨平臺(tái)技術(shù)的未來
預(yù)見不到未來,所以這里拋出幾個(gè)可能性:
- 移動(dòng)跨端只跨 Native 兩端:對(duì)許多移動(dòng)產(chǎn)品而言,體驗(yàn)細(xì)膩、性能優(yōu)異的 Native App 仍是目前最重要的應(yīng)用形態(tài),并且雙端功能完全一致,同等重要,所以只跨 Android、iOS 兩端,統(tǒng)一移動(dòng)端 Native 開發(fā)是相對(duì)合理的方案
- 小程序跨 App 自成一體:如果小程序不能真正標(biāo)準(zhǔn)化,跨 App 投放需求催生出的跨小程序框架方案就有必要存在
- Web 仍是 Web,Hybrid 仍將持續(xù):Web 特性更迭周期太長,移動(dòng)設(shè)備的更迭太慢,等不及 Web 以年為單位的進(jìn)化速度,依靠 Native 增強(qiáng) Web 的 Hybrid 過渡方案很可能長期“過渡”下去
P.S.小程序已經(jīng)在標(biāo)準(zhǔn)化進(jìn)程中了,小程序框架成為標(biāo)準(zhǔn)化的容器也不是沒有可能,畢竟小程序框架不存在 WebView、瀏覽器一樣的慢周期阻力
不看好一招吃遍天下的跨全端的方案,因?yàn)闊o論 universal 組件還是 universal API 都是最小交集,無法滿足實(shí)際需要。并且,真的需要讓一套代碼運(yùn)行在所有渠道、端、平臺(tái)上嗎?