跨端方案的三大困境
- 2020 年 8 月 26 日
- 筆記
- Experience
寫在前面
2018 年,Airbnb 放棄了繼續使用 React Native,箇中原因主要有兩方面:
-
技術:成熟度、配套設施/類庫建設成本、首屏性能硬傷等沒能很好地解決
-
團隊組織:工程師要求高、跨技術棧/跨團隊調試/測試等也產生了新的問題
實際上,跨端方案遭遇的問題遠不止這些,一些時候 Write Once, Run Everywhere 只是美好願景
一.技術困境
一言以蔽之,觸碰到能力邊界之前,跨端方案里的一切都是美好的
以 React Native 為例:
Bridge 層通過消息通訊將 JavaScript 世界與 Native 世界聯繫起來
Shadow Tree 用來定義 UI 效果及交互功能,Native Modules 提供 Native 功能(比如藍牙),二者之間通過 JSON 消息相互通訊
P.S.圖有些舊,但不影響理解原理,更新的 React Native 架構圖見[(React Native 架構演進]//www.ayqy.net/blog/react-native-new-architecture/)
在這樣的技術架構中,寫的和實際執行的都是 JavaScript,調用由 Native 提供的視圖渲染能力及平台特定能力,Facebook 稱之為Scripting native 方案,姑且叫做容器化 Native 跨端方案:
將 Native App 改造成標準化的容器,進而允許一套程式碼跨多端標準容器運行,如 React Native/Weex、Flutter
(摘自移動端跨平台技術之下的變與不變)
容器能力在很大程度上決定著開發效率,在容器提供了一致的標準支援範圍內,能夠愉快地一人搞定多端。然而,一旦觸及能力邊界,就會面臨高成本的多層聯合開發(Native 層、JavaScript 引擎層、特定業務領域層、業務層……),人效上並沒有優勢。另一方面,如何保持多端一致性,也是個極其複雜並且充滿技術挑戰的問題
此外,相關的配套能力也直接關係到開發效率:
-
調試:跨技術棧調試一直是難題,問題排查成本越來越高
-
性能:跨執行緒、跨頁面耗時分析困難、性能工具鏈缺失
-
工程鏈路:由於技術方案的特殊性,需要量身訂製許多配套設施(包括但不限於 IDE、調試、性能、CI/CD、監控),才能將各個環節的成本降下來
總的來說,技術上最大的困境在於:
-
抹不平的多端差異
-
掀不開的 JavaScript 引擎蓋
-
跟不上的配套能力
多端一致性在技術投入上幾乎是無底洞,底層的平台架構差異(UI 渲染方式、事件機制、系統 API)根深蒂固,以各類跨端方案目前的成熟度僅能覆蓋極其有限的一部分,留有非常大的空白需要通過擴展容器能力來填補,包括通用的基礎能力(如 UI、交互),以及面向業務領域的特定能力(如多媒體、定位)
引入 JavaScript 引擎雖然獲得了動態執行程式碼的能力,但也帶來了技術上的不確定性,幾乎無法跟蹤解決 JavaScript 引擎內部的崩潰或異常行為
通用的基礎設施大多無法直接用於跨端場景,邊邊角角的配套能力都需要花力氣建設,而為了滿足業務快速生長,總是優先建設核心關鍵能力,配套支援通常是滯後的,同樣影響著效率
Flutter 能帶來一些不同嗎?
事實上,Flutter(目前看起來)同樣面臨這些技術困境,技術實現的變化並未徹底改變局面
據 2020 Q1 調查結果,Flutter 開發者認為最重要的 6 個問題是:
-
調試錯誤和崩潰
-
測試確保 App 能夠跨多平台運行
-
選用狀態管理方案
-
理解和處理布局問題(如文本溢出)
-
根據設計稿創建 UI
-
排查特定平台問題
同時,認為最困難的 6 個問題是:
-
排查特定平台問題
-
記憶體問題的診斷和修復
-
CPU 使用率問題的診斷和修復
-
接入現有的 Native API
-
UI 卡頓問題的診斷和修復
-
開發特定平台的 Flutter 插件
因此,跨端方案的調試、性能之痛仍在 Flutter 延續,多端差異以及配套能力的困境並沒有改變
二.團隊組織困境
與單端開發模式相比,跨端方案的協作成本更高,體現在:
-
跨團隊
-
鏈路長
-
容器團隊壓力大
-
職責邊界不清晰
跨端方案下,跨團隊協作成為了最主要的協作方式,需求串講、開發、聯調、問題排查等多個環節都需要跨團隊溝通/協作,溝通成本不容忽視
長鏈路意味著技術細節散落在多層,各自只擁有一小部分知識:
表層業務邏輯 ----------------------------- 特定業務領域框架 ----------------------------- 通用前端框架/類庫 ----------------------------- JavaScript引擎(擴展) ----------------------------- Native Module | 特定業務領域能力 ----------------------------- Native通用框架 ----------------------------- Native View ----------------------------- 平台作業系統
由於每個團隊都看不到全景,每一個原因不那麼顯而易見的問題就都要一層層向下排查,甚至涉及特定業務領域能力的部分又分為許多層……
另一方面,如此繁多的層次也造成了複雜度堆積,越往下層複雜度越高,因為不確定的可變輸入越多,越難弄明白來龍去脈,排查問題的成本也越高
理想情況下,按漏斗模型逐層過濾,每一層只需要檢查自己的輸入輸出,但滯後的配套能力讓表層業務難以識別出問題所在的範圍,於是容器團隊成為了問題流轉的過濾閥,上接紛繁的 JavaScript 業務,下連複雜的特定領域能力,大量的時間耗費在了弄清楚來龍去脈上,容器能力擴展被迫降速,反覆排查已知問題……
業務視角下,對業務之下的層次職責劃分並不十分清楚,因此很容易找錯層/人,產生無效的「重定向」。而容器層同樣也不具備全景視圖,問題流轉軌跡變得相當曲折,溝通成本充斥在各個環節中,制約著開發效率
三.個體困境
對個體而言,面臨的最大困難是跨端方案與 Web 標準存在些許差異,並且這些許差異不像 W3C 標準一樣能寫得清清楚楚:
Weex enables developers to use modern web development skills to build Android, iOS, and Web apps with a single codebase.
也就是說,通用的 Web 經驗不完全適用,學習曲線並不十分友好,例如:
-
rem、媒體查詢、scale/zoom等適配經驗都不一定適用
-
減少 DOM 操作、合併 JavaScript 文件、開啟硬體加速等常規優化措施也不一定能產生明顯的性能優化效果
-
(像學習 Web 一樣)只了解瀏覽器之上的標準能力是不夠的,想要真正高效地完成業務開發工作,容器原理甚至部分實現細節都要理解
就像有 Native 背景的開發者學習TypeScript一樣,初接觸無師自通,熟悉的Class、Interface、靜態類型用起來遊刃有餘……然而,熟知 TypeScript 的開發者一定知道個中細節存在著多少奇怪的地方
四.跨端的真正意義是什麼?
React Native 最初的出發點是:
希望 Native 開發也能像 Web 一樣 Move fast
- 快速迭代(Rapid iteration cycle):Web 一天兩版,產品迭代周期更短
- 快速回饋(Immediate testing feedback):Web 發布立即觸達用戶,A/B test 等實驗結果立等可取,產品演進更快
- 快速開發(Rapid development velocity):刷新瀏覽器即可生效,不必等待重新編譯 App
(摘自React Native 簡史)
因此,從需求角度來看,開發效率是次要的,動態化的靈活性、快速迭代助業務先贏才是其跨端的主要意義,或者說追求的是生產效率,而不僅是開發效率,更短的迭代周期,更快速的觸達用戶都是直接的生產效率進步
然而,在三大困境之下,開發效率實際上也嚴重影響著生產效率,但還不足以抵消快速迭代、動態發布的重大進步,此消彼長也算是一種平衡,一種可接受的妥協
五.在困境中尋找生門
理想情況下,容器應該是趨於標準化的,提供多端一致、豐富穩定的能力支援,之上的業務棧極少觸及容器能力邊界,從而使得容器層能夠不斷優化探索,更好地滿足業務發展的需要
另一方面,跨端方案只是將多端不一致性帶來的複雜度下沉到了容器層,獨立於平台的語言環境(JavaScript 引擎、Dart 虛擬機等)能夠保證上層業務邏輯的一致性,但容器層仍然需要在多端各自實現一套,如何保證容器能力的多端一致性,仍然是個大問題,也並不比非跨端方案下容易多少
因此,首先要解決容器能力豐富度的問題,將邊界拓寬,從根源上減少問題。轉而集中火力到真正的難題上,攻下最有價值的難點部分。同時通過虛擬架構等方式建立全職能的業務支撐團隊,降低溝通成本:
-
業務要有自研能力:化解下層資源瓶頸,共同豐富容器能力
-
專註必須花大力氣投入的點:調試能力、標準化、性能分析以及持續跟蹤、工程配套設施
-
要有全職能的業務支撐團隊:有能力兜住所有問題,真正提供一攬子解決方案,消除無意義的溝通重定向
其中,業務自研能力先要有標準的擴展方式,要求容器實現上易擴展,業務開發者不需要了解過多細節也能快速進入開發。調試能力在長鏈路的技術棧下至關重要,問題識別成本越低、準確率越高,效率越高,所能釋放出來的資源就越多
從業務開發角度來看,更需要的可能是一層網關,請求過去響應回來,而不是一系列路由表,需要一跳一跳地跟蹤。全職能的業務支撐團隊組成區域網,讓網關之後的流量得以快速流轉,高效協作的同時提升業務開發的幸福感
參考資料