溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

前端開發(fā)中怎么正確地跨端

發(fā)布時間:2022-01-12 13:57:38 來源:億速云 閱讀:166 作者:柒染 欄目:云計算

這期內容當中小編將會給大家?guī)碛嘘P前端開發(fā)中怎么正確地跨端,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

跨端

Write once, run everywhere。

我們都聽說過這句經典的宣傳用語,后來我們都知道,沒有什么東西是可以真正 run everywhere 的,充其量也只能做到 debug everywhere。

而當我們談論一次編寫多端運行時,顯然不可能真的指跨一切所有端,大多數(shù)情況下你不會需要在電腦和手環(huán)上同步開發(fā)一個功能。

  • 跨 PC 和無線端。

  • 跨多 Native 平臺:例如跨 Android 和 iOS,甚至跨 Windows。

  • 跨投放 APP:隨著超級 APP 越來越多,很多業(yè)務需要在多個 APP 中投放同一個頁面。

  • 跨 Web 和 APP:Web 在很多情況下仍然是不可避免的,我們的頁面可能需要分享、SEO 或者投放到 M 站上等等,這時候就需要同時能在 Web 和 APP 內運行。

  • 跨 Web、多小程序、QuickApp 等:其實本來類似跨 APP,但是奈何小程序本身是各家控制的封閉生態(tài),故而有了開發(fā)一次適配到多種封閉生態(tài)的訴求。

  • 其他端的跨端訴求:例如跨 POS 機,手表等。

與我們多種多樣的跨端訴求相對應的,是百花齊放的跨端方案。

前端開發(fā)中怎么正確地跨端

百花齊放的跨端方案

以 Web 為基礎的 H5 Hybrid 方案

這類方案最為直接,簡單來說就是用網(wǎng)頁來跨端。由于我們絕大多數(shù)端上(甚至包括封閉的小程序生態(tài))都支持 Webview,所以只要開發(fā)網(wǎng)頁然后投放到多個端即可,在桌面端對應的方案就是 Electron。

為什么不直接全用 Web?

從開發(fā)成本低、標準統(tǒng)一、生態(tài)繁榮上來說,H5 Hybrid 方案基本是不二之選。然而這種方案難以避免在性能和體驗上存在差距。Web 的生態(tài)繁榮來自于其良好的歷史兼容性,也意味著沉重的歷史包袱。

  • W3C 標準作為開放技術標準,歷史包袱多,邏輯復雜。

  • Web 標準在設計上不是 Design for Performance 的,導致很多地方難以進一步改善,例如 JS 執(zhí)行和 Layout、渲染互斥無法并行,導致過長的 JS 執(zhí)行任務會執(zhí)行正常的渲染導致卡頓。

  • Web 的標準化在推進上也比較慢,新的能力可能要比較長的時間才能使用。

React-Native/Weex 類方案

在移動平臺上尤其是早期 WebView 的性能體驗非常糟糕,前面我們也提到這種差距主要來自于 Web 生態(tài)本身沉重的歷史負擔。

而 React-Native/Weex 這類方案通過盡可能的取長補短,通過結合 Web 的生態(tài)和 Native 的組件,讓 JS 執(zhí)行代碼后用 Native 的組件進行渲染。由于拋棄了 Web 的歷史包袱,這類方案可以做一些大刀闊斧的改動。

例如 RN 就如下圖中,把 JS 執(zhí)行、布局(Yoga)和渲染(Native 組件)放在三個進程分開執(zhí)行,避免了 JS 執(zhí)行復雜任務時界面卡頓。通過拋棄 CSS 中的大量標準,只支持部分 flex 布局能力來減少布局和渲染的復雜度。

前端開發(fā)中怎么正確地跨端

這種方案同樣存在一些缺陷:

  • iOS/Android 雙端本身不一致的組件和布局機制,讓雙端一致性難以得到保障。

  • 依賴于 Native 機制也讓一些 CSS 屬性實現(xiàn)起來比較困難,例如老大難的 z-index 問題。

而最麻煩的一點在于,這套方案意味著非常高的維護支持成本。

  • 借用了 Web 的生態(tài)但并不完全是 Web 生態(tài),很多地方不一致,最常見的吐槽就是慣用的 CSS 布局方式無法使用。

  • 相比于瀏覽器新增一個傳感器 API 都要配套完善的 devtool,這類方案大部分情況下的開發(fā)體驗保障可以說是刀耕火種(下圖為 Chrome 的方向傳感器 API 的 devtool)。

前端開發(fā)中怎么正確地跨端

在 WebView 性能差距逐漸縮小的今天,維護這一套復雜方案的 ROI 是否值得,需要根據(jù)我們場景的具體訴求考量。

Flutter

Flutter 要解決的問題和上面的方案不同,完全不打算繼續(xù)在 Web 生態(tài)上借力,從設計之初也并沒有把 Web 生態(tài)考慮進去。相比于 RN 依賴 Native View 渲染,F(xiàn)lutter 則是自繪的組件,直接通過 Skia 繪制到屏幕上。

由于可以完全發(fā)揮 GPU 的能力,也不需要去 Native 繞一圈。Flutter 理論上能做到更好的性能和兩端一致性,這一意味著理論上未來可能基于 Flutter 的 JS 動態(tài)化方案能夠在樣式上支持的比 WEEX 更好。

從前端的視角看仍然更像是一個 Native 開發(fā)方案而非跨端方案(雖然其實是跨 Android/iOS 的)。目前最主要的問題是 Flutter for Web 從技術原理上來說離生產可用可能還非常遙遠。除此之外動態(tài)化能力的確實也會讓部分場景不適用。

研發(fā)框架 for 小程序

小程序是被創(chuàng)造出來的問題,各家小程序出于商業(yè)上的考量主動在 Web 生態(tài)的基礎上構造了相對封閉的生態(tài)。導致和 Web 生態(tài)格格不入。然而有多端小程序投放,或者同時投放小程序和 Web 端的場景難以接受使用。

由于小程序的端封閉且不受控,要解決小程序的跨端問題往往只能從研發(fā)框架層面出發(fā)。

編譯時方案

比較知名的編譯時方案是 Taro,大致的原理可以解釋為將 JSX 編譯到小程序的 WXML/WXSS/JS 上,而這類框架的實現(xiàn)原理其實并非真的是一個 React 或者類 React 框架,而是把看起來像是 JSX 的模板通過靜態(tài)編譯的方式翻譯成小程序自身的模板。

這樣做的限制非常明顯,那就是 JSX 是 JavaScript 的拓展語言(React Blog 寫的是 is a syntax extension to JavaScript),而小程序所采用的 WXML 卻是一個表達能力非常受限的模板語言,我們不可能完成從一個通用編程語言到模板語言的編譯。

而靜態(tài)編譯類框架為了做到這一點,采取的方式就是限制開發(fā)者的寫法,這也是為什么 taro 對 JSX 的寫法做出了諸多限制。這一點直接導致了無窮盡的維護成本和嚴重受損的開發(fā)體驗,而后 taro/next 也轉向了運行時方案 + 靜態(tài)編譯優(yōu)化的結合。

運行時方案

不謙虛的說,針對小程序的運行時方案應該是最早我在寫下 remax 第一個 issue 時[1]提出的。

通過 React Reconciler(類似于 Rax Driver)我們可以讓運行在小程序容器中的 React 不去直接操作 DOM,而是把操作的數(shù)據(jù)通過 setData 傳遞給小程序的 View 層映射到最后的界面上。

雖然 Remax、Rax 運行時、Taro Next 等幾種方案不盡相同,但是思路大同小異,就是利用小程序模板一定程度上的動態(tài)化能力 + 類 React 框架的 VirtualDOM 來進行渲染。當然這種做法相對于小程序原生的渲染方式存在一定的性能損耗。

前端開發(fā)中怎么正確地跨端

remax 的支付寶端性能測試

在部分場景下,這種損耗是值得的。這些運行時框架也都在陸續(xù)通過允許關掉編譯產生的模板中的不用的屬性、部分靜態(tài)編譯、虛擬列表等方式來改進性能。

當然了,最后內嵌 Webview 仍然是一個方案。

作為業(yè)務技術團隊,我們該做什么

上面介紹的都是針對某些具體的場景的一些解決方案,然而對于業(yè)務技術團隊來說,跨端的本質是提效。針對新的變化提出新的方案是一方面,更重要的如何讓這種提效真的長治久安,讓我們的提效不會變成從一個新方案跳到另外一個新方案。

讓我們重新看上面這張圖,可以確定的是,跨端的訴求和與之對應的方案仍然會處于頻繁的變化中,也不會出現(xiàn)一個解決所有跨端問題的方案。而其中相對不變的部分是值得我們?yōu)榱碎L治久安必須要投入的。

前端開發(fā)中怎么正確地跨端

WebView & H5 Hybrid

WebView 可能是眾多容器中最為特殊的一個,雖然很難滿足部分場景對于性能和體驗的極致要求,但是會是最穩(wěn)定、長期存在且得到支持的方案。

從開發(fā)效率和未來長期的維護演變來看,在能夠滿足性能體驗要求的前提下,Web 方案仍然是最優(yōu)先應該考慮的。

同時,在 APP 的 WebView 容器上我們能做更多的工作,例如通過容器來提供一些端內的能力,結合 Native 能力實現(xiàn)的并行數(shù)據(jù)加載,頁面?;畹鹊?。

基礎建設

無論采用何種跨端方案,在哪個容器中,性能、穩(wěn)定性、效能都是繞不開的三駕馬車。

性能

對于不同的方案往往存在不同的性能方案,上面我們也提到在小程序的運行時方案中就會有減少編譯模板產出的字段這樣的優(yōu)化。然而,其實除了這種特定方案的優(yōu)化外,大部分優(yōu)化手段是大同小異的:離線緩存、數(shù)據(jù)預取、快照、SSR、NSR 等等方案。

對于不同的端和容器,對于性能問題的度量和發(fā)現(xiàn)也應該是一致的,我們需要對頁面在不同端的性能究竟如何有明確的感知和橫向對比。

性能的端側建設(端能力、具體到某一個端的性能測算方案、性能打點等)可能需要根據(jù)不同的端、不同的跨端方案而不同。但性能的基礎建設(首屏標準、數(shù)據(jù)分析、基礎優(yōu)化能力)在跨端中應該是相對穩(wěn)定的。

在端側能力方面,ICBU 早期在 WEEX 性能優(yōu)化時引入了并行加載的能力,通過 wh_prefetch 協(xié)議來使用容器的并行加載能力。而后在新的容器(WebView、瀏覽器)中,雖然底層能力存在差異,但仍然識別相同的協(xié)議。

前端開發(fā)中怎么正確地跨端

在數(shù)據(jù)采集和分析方面,我們通過統(tǒng)一跨端基礎庫,讓不同端不同技術方案可以在同樣的標準下分析、度量和對比。

前端開發(fā)中怎么正確地跨端

穩(wěn)定性建設

在無線端我們常常把性能 & 穩(wěn)定性并稱為 “高可用”,穩(wěn)定性主要涵蓋的范圍包括灰度能力、業(yè)務監(jiān)控、報警、錯誤監(jiān)控、白屏檢測等等。

這些能力相比起來對具體端和跨端方案的依賴更少,除了在端側的數(shù)據(jù)采集邏輯稍有區(qū)別外其他建設部分相對也是比較穩(wěn)定的。集團針對這些場景也存在一些跨端可用的方案、例如 iTrace 等。

工程基建

對于不同場景的跨端,雖然在方案上存在一定的差異,但是我們的工程基建是可以保持統(tǒng)一

  • 容器層提供統(tǒng)一的 API 和文檔能力

  • 統(tǒng)一的研發(fā)流程

  • 研發(fā)工具提供統(tǒng)一的抓包、debug 能力等

  • 一致的工具庫等等

這樣,當有新的容器或者方案出現(xiàn)時,我們只需要按照相應的能力進行對齊,就能讓我們上層的業(yè)務代碼和開發(fā)體驗維持相對穩(wěn)定的狀態(tài)。

前端開發(fā)中怎么正確地跨端

業(yè)務邏輯跨端

相對來說,我們會發(fā)現(xiàn)在多種跨端方案的演化中,如何渲染、如何布局等 UI 層面的變化要遠遠大于業(yè)務邏輯層面。甚至是小程序和 Flutter,其大致的開發(fā)范式都沒有發(fā)生太大的改變。例如 Flutter 開發(fā)范式和 React 非常相似,同樣是聲明式 UI,同樣存在 VirtualDOM。

考慮到 SEO 和性能等問題和 Flutter 本身基于 Skia 的渲染模式,F(xiàn)lutter for Web 在相當長一段時間內可能都不會是一個生產環(huán)境可用的方案。

而在統(tǒng)一了業(yè)務邏輯代碼的組織方式后,我們可以通過 Hooks for ALL 的方案讓 Flutter 和 Web 端可以共享一份基于 Hooks 的業(yè)務邏輯代碼。

前端開發(fā)中怎么正確地跨端

有時候你不需要真的 run everywhere,能夠提高效能、保持一致就已經達到目的了。

視圖層

目前來看視圖層的跨端仍然充滿了變數(shù),在我們的業(yè)務邏輯層跨端做的足夠原子化后,也許我們部分交互邏輯不是特別重的視圖層能夠通過 DX + 綁定原子化邏輯 + 數(shù)據(jù)參數(shù)的方式覆蓋更多的跨端場景。從而同時滿足性能、效能方面的訴求。

然而對于通用場景的視圖跨端,仍然沒有銀彈。

上述就是小編為大家分享的前端開發(fā)中怎么正確地跨端了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI