移動前端開發(fā)和Web前端開發(fā)的區(qū)別是什么?
前端這門技術(shù),從誕生發(fā)展至今不過寥寥十余年。如果說前十年是 PC 前端的時代,那后十年一定是屬于移動前端的時代。特別是隨著網(wǎng)絡(luò)制式的發(fā)展,移動設(shè)備在全球范圍內(nèi)得到了空前的普及,在前端領(lǐng)域,Hybird Web、React Native、Weex、Flutter 等等一系列新的移動前端技術(shù)也如同雨后春筍般冒出來,今天來和大家分享一下我對「移動前端開發(fā)和 Web 前端開發(fā)」的理解。
前端這門技術(shù),從誕生發(fā)展至今不過寥寥十余年。如果說前十年是 PC 前端的時代,那后十年一定是屬于移動前端的時代。特別是隨著網(wǎng)絡(luò)制式的發(fā)展,移動設(shè)備在全球范圍內(nèi)得到了空前的普及,在前端領(lǐng)域,Hybird Web、React Native、Weex、Flutter 等等一系列新的移動前端技術(shù)也如同雨后春筍般冒出來,今天來和大家分享一下我對「移動前端開發(fā)和 Web 前端開發(fā)」的理解。
回顧:前端發(fā)展史
▐ 階段一:刀耕火種
十多年前的前端,開發(fā)者還在為兼容 IE6 而頭疼,框架上 jQuery 是老大,有追求的前端開發(fā)可能會使用 Zepto.js 以減少網(wǎng)頁體積。這個時候,前端頁面主要還是以 PC 為主,這個時候根本沒有移動前端的概念,在小小的手機屏幕上流量的頁面則是以純文本為主。
▐ 階段二:工程化
在 2011 ~ 2014 年之間的歷史階段里,模塊化的思路占為主導(dǎo)。當(dāng)時為了進行 Assets 資源加載器的設(shè)計,就制定了模塊化的協(xié)議規(guī)范。當(dāng)時比較流行的模塊化協(xié)議就是 AMD(RequireJS)、CMD(Seajs 為代表)、KMD(Kissy 為代表)。在淘寶、天貓,Kissy 應(yīng)用的很火,所以 KMD 主導(dǎo)天下;在支付寶及外部社區(qū),Seajs 應(yīng)用的很火,所以 CMD 主導(dǎo)天下,玉伯大大的名氣和威望也在前端圈里特別高;而 AMD 在國外比較流行,但漸漸也被后來出現(xiàn)的 CommonJS 規(guī)范削弱了氣勢。
▐ 階段三:移動化
隨著 3G、4G 的發(fā)展和 iOS 和 Android 手機在市場的普及量大增,PC 業(yè)務(wù)主戰(zhàn)場也逐漸過渡到移動端。前端的思維模式由 PC 轉(zhuǎn)向了移動端,并向 App 的用戶體驗看齊。移動端的 HTML5 協(xié)議支持不完善,前端的生產(chǎn)配套不全,Android 的屏幕碎片化,所以那個時候的前端開發(fā)移動端頁面適配的痛苦要遠遠超過 PC 時代。
▐ 階段四:框架化
在前端社區(qū),Angular、React、Vue、RN (React Native) 這樣的 MV* 框架一個接著一個出現(xiàn),讓前端接受了數(shù)據(jù)驅(qū)動思想的洗禮之外,還借助 RN 完成了移動端的體驗升級,包括后來的 Weex、Flutter。
在這個階段,前端開始有了終端的底層架構(gòu)組,開始構(gòu)思前端頁面在移動終端上的加載性能和用戶體驗表現(xiàn)。在阿里巴巴內(nèi)部,為了解決多端復(fù)用的問題,Rax 借助 VDOM 打通 WebView 和 Weex 兩端,一套代碼跑天下。
▐ 階段五:垂直化
隨著初代 iPhone 的發(fā)布,大屏幕手機逐漸變成了主流,移動端的需求開始爆發(fā)。在淘寶天貓,每年雙十一的移動端成交額逐年攀升,并逐漸占領(lǐng)絕對領(lǐng)先地位。前端的領(lǐng)域也隨著這種趨勢逐漸細分,按照場景可以簡單分為移動(無線)前端開發(fā)和中后臺前端開發(fā)。
移動前端開發(fā)面向的是消費者端的 Web 與 輕 App 業(yè)務(wù)場景,在這個場景下,淘系經(jīng)過多年的營銷活動沉淀,逐漸形成了移動端獨特的、輕量級的解決方案,以及模塊維度的、面向運營的頁面搭建系統(tǒng)。
中后臺前端則是面向企業(yè) ERP、CRM 、OA 等偏后的業(yè)務(wù)場景,如商家后臺等系統(tǒng)。在這個場景下,借助飛冰、Fusion Design 等中后臺物料,形成可視化的中后臺搭建解決方案,為業(yè)務(wù)的前端、開發(fā)或產(chǎn)品角色提供一站式中后臺生產(chǎn)解決方案。
移動前端:混合技術(shù)的前世今生
曾幾何時,移動客戶端開發(fā)和前端開發(fā)是兩條沒有交集的平行線,但現(xiàn)在我們越來越擁抱兩者的合作產(chǎn)物:混合式(Hybird)應(yīng)用開發(fā),或者用最近比較火的一個概念 -- 大前端技術(shù)。
從技術(shù)的表現(xiàn)形式思考,本質(zhì)上客戶端開發(fā)與前端開發(fā)都是終端技術(shù),它的特點是直接面向用戶 UI 編程。
▐ 同是 UI 編程,我們面對的痛點是什么?
傳統(tǒng) Web 前端技術(shù)的技術(shù)局限性
1、資源加載:HTML、JS、CSS、圖片等靜態(tài)資源存放于遠端的服務(wù)器,需要動態(tài)的異步拉取,再拉取數(shù)據(jù)進行展示,初始化效率上比 Native 慢的多
2、渲染機制:在瀏覽器的設(shè)計中,JS 的執(zhí)行和頁面的布局、Paint 都在同一個主線程,無法并行化,再加上 JS 的性能趕不上 AOT 語言,執(zhí)行復(fù)雜邏輯時導(dǎo)致的卡頓通常會阻塞 UI,再加上冗長的渲染管線,導(dǎo)致瀏覽器的渲染體驗在等量對比 Native 時并不占優(yōu)勢。
3、頁面切換:在瀏覽器中并不存在路由的概念,這導(dǎo)致頁面間的切換體驗完全依賴于瀏覽器 Shell 提供的能力,在頁面切換的時候會反復(fù)加載。當(dāng)然前端社區(qū)中也出現(xiàn)了單頁面應(yīng)用的概念,但是多個頁面的資源也顯著增加了 JSBundle 的體積,也使頁面的開發(fā)更加復(fù)雜化了。
4、API 能力:瀏覽器的安全機制是基于同源策略的沙箱機制,這套沙箱機制阻止了前端開發(fā)者使用原生系統(tǒng)能力,你只能使用 W3C 標(biāo)準(zhǔn)定義的功能,而且考慮到終端碎片化的問題,這些接口往往不能直接使用。這在 PC 端的場景中是沒有什么問題的,但是在移動端則相反,開發(fā)者希望有能力調(diào)用系統(tǒng)接口實現(xiàn)一些更富交互的場景。
5、交互性能:瀏覽器的實時交互性能體驗差,在復(fù)雜交互場景中大規(guī)模的重排限制了 UI 幀率,這種限制在中低端移動設(shè)備中尤為嚴(yán)重。
6、腳本語言,動態(tài)解析執(zhí)行
JS 是一門 JIT 語言,也就是需要動態(tài)解析執(zhí)行,對比預(yù)先編譯機器碼的 AOT 語言的執(zhí)行性能就差得多了。
傳統(tǒng)客戶端技術(shù)的局限性?
1、動態(tài)性:客戶端開發(fā)通常是有固定的版本發(fā)布計劃,而且受制于 Apple 的 App Store 審核規(guī)則,版本發(fā)布的不確定性還會受到政策影響,Android 在國內(nèi)的渠道眾多,每次發(fā)版都要反復(fù)檢查渠道,一旦發(fā)現(xiàn)線上問題需要依賴再次發(fā)版,容錯成本非常高,這也大大增加了對業(yè)務(wù)的局限性。
2、開發(fā)成本:客戶端的開發(fā)成本高,然而生態(tài)還不如 Web 豐富,npm 社區(qū)的幾萬開源包,加上更活躍的開發(fā)者社區(qū),導(dǎo)致對企業(yè)來講客戶端的研發(fā)成本是高于 Web 開發(fā)的。
3、跨端一致性:傳統(tǒng)客戶端開發(fā)一套業(yè)務(wù),是需要實現(xiàn) Android + iOS 兩套代碼的,而且由于 Android 和 iOS 的操作系統(tǒng)能力差異,同樣的需求往往會用不同的視覺和交互來實現(xiàn),這也導(dǎo)致了業(yè)務(wù)成本居高不下。
▐ 混合式前端開發(fā)
為什么會出現(xiàn)混合式前端開發(fā)?
隨著 iOS + Android 確立了移動操作系統(tǒng)的統(tǒng)治地位,前端開發(fā)者也在尋找使用操作系統(tǒng)提供的能力進行業(yè)務(wù)開發(fā)的模式。Web 的開發(fā)方式遠比 iOS 和 Android 更加方便和高效,Web 上層出不窮的各種庫和框架也遠比 Android 和 iOS 的各種庫和框架方便的多。Web 上我們可以方便的使用各種前端框架,及時預(yù)覽效果(想想大型 Android/iOS 工程的編譯時間)。
從阿里巴巴的角度來看,隨著中臺化的理念逐漸被接受:業(yè)務(wù)需要追求快速發(fā)展,前臺的 UI 和需求會隨著商業(yè)決策快速迭代,前端和客戶端不同的崗位也形成了分工化的研發(fā)模式。
前端向上,前置作為業(yè)務(wù)方的唯一接口,逐漸演變?yōu)榇笄岸说臉I(yè)務(wù)層。在這一層,它的職責(zé)是負責(zé)定義規(guī)范,通過框架規(guī)范業(yè)務(wù)的開發(fā)過程,同時封裝統(tǒng)一的解決方案和工程化能力,將重復(fù)的工作抽離。
客戶端向下扎,解耦業(yè)務(wù)需求,轉(zhuǎn)為大前端的架構(gòu)層,給上層的業(yè)務(wù)開發(fā)者提供能力支持。通過將客戶端的系統(tǒng)級 API 以及宿主應(yīng)用的能力暴露給上層前端,提高前端頁面對更多富交互場景的承載能力。
在這樣的大背景下,各種混合開發(fā)技術(shù)層出不窮,在這里我們簡單的把混合式應(yīng)用的發(fā)展定義為三個階段:
▐ 階段一:JSBridge
在這個階段,主要還是以 WebView 為主,并配合 JSBridge 提供了 Naive 與 JS 之間的通信鏈路,基于這個通信基礎(chǔ),Native可以暴露出一些標(biāo)準(zhǔn)服務(wù) API 提供給 JS 調(diào)用,同樣的 JS 也可以以此封裝一些基礎(chǔ)API給 Native 調(diào)用。前端開發(fā)者使用傳統(tǒng)的 JS + HTML + CSS 進行頁面的開發(fā),并且調(diào)用 JSBridge API 驅(qū)動客戶端能力。在這個階段,Apache Cordova 是業(yè)內(nèi)的佼佼者,大多互聯(lián)網(wǎng)公司內(nèi)部也有自己的 JSBridge 框架實現(xiàn),可以說 JSBridge 第一次給了前端開發(fā)者調(diào)用 Native 的能力。
但是 JSBridge 方案的主要缺點在于性能方面及高級組件擴展能力缺失,流暢性始終無法與 Native 媲美。
▐ 階段二:原生 UI
雖然 Web 的動態(tài)性和高效的開發(fā)效率,是原生開發(fā)望塵莫及的,但是瀏覽器技術(shù)的瓶頸也非常明顯:
1、W3C 作為開放的技術(shù)標(biāo)準(zhǔn),歷史悠久,包袱多,顯著拖慢了瀏覽器的性能。
2、WebView 渲染引擎設(shè)計的上的缺陷,渲染流水線非常長,導(dǎo)致瀏覽器對合成器動畫和非合成器動畫區(qū)別對待,非合成動畫性能不好。
3、單線程模型,無法發(fā)揮現(xiàn)代硬件架構(gòu)特別是 ARM 架構(gòu)多核心的性能。
4、異步光柵化的設(shè)計,在進行長列表滾動時,不可避免出現(xiàn)白屏的現(xiàn)象。
**有沒有一種兩全其美的方式?
React Native/Weex 的出現(xiàn)給前端開發(fā)者帶來了一道曙光。**
React Native/Weex 利用 JS 引擎來調(diào)用 Native 端的組件,從而實現(xiàn)相應(yīng)的功能。React Native 和 Weex 都允許前端開發(fā)者使用 JS 進行業(yè)務(wù)邏輯開發(fā),使用 VDOM 來描述文檔結(jié)構(gòu),并配合 CSS 的子集來定制樣式,樣式和模板分離。
Weex 體系中, JS 的執(zhí)行在 JS Thread,Layout 執(zhí)行在獨立的 Layout Thread ,渲染執(zhí)行在系統(tǒng)的 MainThread ,三個線程相互獨立,并行執(zhí)行。
在 WebView 的體系中 JS 的執(zhí)行、 Layout 、 Paint 都在 MainThread ,相互影響,在進行復(fù)雜任務(wù)時會導(dǎo)致界面卡頓。
這種方案的優(yōu)勢在于最大化的復(fù)用前端的生態(tài)和 Native 的生態(tài)體系。
在阿里巴巴,Weex 的大規(guī)模應(yīng)用,甚至支撐起了雙十一億級的流量。
▐ 階段三:自繪引擎
什么是自繪引擎?
所謂自繪引擎,就是不依賴操作系統(tǒng)提供的布局、原生組件能力,直接調(diào)用 GPU 或者底層抽象層進行繪制的渲染引擎。
在上一個階段,前端開發(fā)者已經(jīng)可以使用 JS 引擎驅(qū)動原生 UI 了,為什么還需要自繪引擎?
React Native/Weex 充分將 Native 的 View 體系輸出到前端體系中,在進行 Android/iOS Native View 的封裝過程中,存在不少難以逾越的障礙。如:難以抹平的雙端一致性問題、復(fù)雜樣式能力難以實現(xiàn)、 Layout 動畫需要執(zhí)行兩次(WeexCore Layout 和 Android Native 本身的 Layout )。組件的封裝成本隨著復(fù)雜度增加也越來越高,難以逾越 Native View 限制提供更細致的 W3C 標(biāo)準(zhǔn)能力。
2018 年 Flutter 誕生,通過 Dart 語言構(gòu)建一套跨平臺的開發(fā)組件,所有組件基于 Skia 引擎自繪,在性能上和 Native 平臺的 View 相媲美,同時解決了上一代架構(gòu)難以解決的雙端一致性等問題。引起大家廣泛關(guān)注,充分驗證了通過繪制構(gòu)建組件做到 Native View 媲美的 UI 渲染引擎的可行性。
但是 Flutter 本身是缺乏動態(tài)更新特性的,社區(qū)上也有一些項目在探索 Flutter 的動態(tài)化特性,我們團隊內(nèi)部也在實現(xiàn)面向前端的動態(tài)化 Flutter 引擎:Kraken,與其它方案不同的是 Kraken 并沒有基于 Flutter 自帶的 Widgets 框架進行擴展,而是從底層擴展了 W3C 標(biāo)準(zhǔn)的 API,這使得它更像一個瀏覽器,也讓 Flutter 面向 Web 開發(fā)者的使用門檻大大降低。
未來:回歸本源
天下大勢,分久必合,合久必分。移動前端開發(fā)本質(zhì)上還是終端開發(fā)的一種形態(tài),不管容器、框架、語言怎么變,在前端開發(fā)者中只有 W3C 的標(biāo)準(zhǔn)是永遠不變的。筆者認(rèn)為,隨著 Web 的發(fā)展,在解決一系列性能、體驗問題之后,瀏覽器技術(shù)會成為更通用的 UI 編程標(biāo)準(zhǔn)。
▐ PWA
早先年,Google 就已經(jīng)在這一領(lǐng)域內(nèi)努力,推出了 PWA (Progress Web Application) 的概念。
PWA 通過在移動端瀏覽器提供標(biāo)準(zhǔn)化框架,在 Web App 中實現(xiàn)和 Native App 接近的用戶體驗。它的特性其實是一系列 W3C 標(biāo)準(zhǔn)和私有標(biāo)準(zhǔn)集合,簡單的說 PWA 支持:
- 離線加載:通過 Service Worker 等提供的緩存機制,允許用戶在斷網(wǎng)或者弱網(wǎng)的情況下直接讀取離線資源。
- 后臺駐留進程:正常情況下,瀏覽器的頁面關(guān)閉后它的整個生命周期就結(jié)束了,內(nèi)存也得到了釋放。Service Worker 允許頁面在關(guān)閉的情況下繼續(xù)運行,這保證了類似于離線緩存、主動推送等。
- 消息通知:允許 Web 開發(fā)者實現(xiàn)類似 App 的主動推送機制。
- 其它移動 App 的功能特性,如直接保存圖標(biāo)到桌面,允許用戶像正常使用 App 一樣打開 PWA 應(yīng)用;可以隱藏 UI 中的默認(rèn)瀏覽器元素,讓 Web 內(nèi)容全屏展示,從視覺上看讓 Web 應(yīng)用更像一個原生應(yīng)用,有時候你根本無法分辨到底是 Web 應(yīng)用還是原生應(yīng)用。
▐ PHA
當(dāng)然在標(biāo)準(zhǔn)能力不完善,業(yè)務(wù)又需要定制化能力的當(dāng)下,混合式應(yīng)用還會繼續(xù)發(fā)展。
PHA (Progress Hybird Application) 的概念應(yīng)用而生,PHA 是一種漸進式的混合應(yīng)用增強策略, 提供端測的輔助能力,提升 WebView 的渲染性能與體驗。廣義地說,當(dāng)下比較火的小程序、快應(yīng)用都是 PHA 的一種實現(xiàn)。
在淘系內(nèi)部,我們也在實現(xiàn)一套輕量級的 PHA 方案,并且在大促中也取得了不錯的效果,我想后面單獨出一篇關(guān)于 PHA 的文章來闡述。
關(guān)于未來,隨著技術(shù)方案的多樣化、以及端邊界的擴展,我們認(rèn)為最重要的就是效率與性能的問題。
基于大數(shù)據(jù)的機器學(xué)習(xí)能力,移動端上會擁有更高效的 UI 編排能力,最終能讓 UI 渲染實現(xiàn)實時個性化。
基于最近比較熱的 WebAssembly 能力,讓瀏覽器突破 JavaScript 的限制,能擁有更大的想象空間。