攜程Taro多端化探索與實踐
作者簡介
Frank,攜程前端研發(fā),專注前端性能優(yōu)化、一碼多端、工程化建設等領域。
一、業(yè)務背景
隨著移動互聯(lián)網(wǎng)和智能設備的普及,前端開發(fā)人員需要采用多端同構技術來適配不同的終端(小程序、App和Web)。這些終端之間存在著明顯的差異,包括瀏覽器引擎、操作系統(tǒng)、交互方式以及代碼語言等方面。
這些差異給前端開發(fā)人員帶來了不少挑戰(zhàn)。一方面,不同終端采用不同的瀏覽器引擎和操作系統(tǒng),導致頁面渲染和交互行為的表現(xiàn)各不相同。另一方面,不同終端所使用的代碼語言和開發(fā)工具也存在差異,需要開發(fā)人員具備不同的技術背景和知識,才能編寫多份代碼來適配不同的終端。這樣做不僅增加了研發(fā)人員的開發(fā)工作量和代碼維護的難度,還可能導致用戶在不同設備上遇到不一致的用戶體驗,影響產(chǎn)品的質量和用戶滿意度。
為了解決這些問題,多端同構技術應運而生。通過多端同構技術,旅游前端和公共團隊合作多端探索與實踐,根據(jù)不同終端的特性進行靈活的適配和定制。這樣可以減少開發(fā)成本和維護難度,提高開發(fā)效率和代碼的可復用性。同時,多端同構技術還能提供一致的用戶體驗,無論用戶使用哪種設備訪問應用程序,都能獲得相似的界面和功能。
行業(yè)現(xiàn)狀
三端同構
二、多端同構技術選型
在進行多端同構技術選型時,我們需要綜合考慮跨端能力、成本、性能、代碼語言通用性以及現(xiàn)有技術的支持度。這將有助于我們選擇最適合的技術方案,以下是對當前前端主流跨端技術的分析:
Hybrid | React Native | Flutter | Weex | Taro | |
跨端能力 | ★★★★ | ★★ | ★★★ | ★★★ | ★★★★ |
成本 | ★★★★ | ★★ | ★★ | ★★ | ★★★ |
性能 | ★ | ★★★ | ★★★★ | ★★★ | ★★★ |
代碼語言通用性 | ★★★★ | ★★★★ | ★★ | ★★★ | ★★★★ |
攜程支持度 | ★★★ | ★★★★ | ★★★★ | ★ | ★★★★ |
Hybrid:使用JavaScript語言,支持快速構建多端應用。由于依賴于Webview容器來運行,所以其用戶體驗和性能受到一定的限制的。這種限制會導致應用的響應速度變慢,頁面加載時間變長等問題。適用于三端業(yè)務述求比較高,研發(fā)成本又比較低,性能要求不高場景,比如營銷廣告頁。
React Native:使用JavaScript語言開發(fā)的React的組件,支持構建App、Web,不支持原生小程序。App上有接近原生應用的性能和用戶體驗。適用于對小程序性能要求不高的場景。
Flutter:使用Dart語言和自帶的渲染引擎,支持范圍同ReactNative。在渲染速度和用戶體驗方面表現(xiàn)比ReactNative更加出色。由于ios平臺規(guī)則限制,目前對于熱更新支持并不友好。適用于對App性能要求較高,小程序性能要求不高的場景。
Weex:使用JavaScript語言開發(fā)的Vue的組件,支持范圍與性能同ReactNative,社區(qū)活躍度不如ReactNative。
Taro:開放式跨端跨框架解決方案,它提供了一套統(tǒng)一的開發(fā)語法和組件規(guī)范,使開發(fā)人員能夠使用一套代碼來開發(fā)適配不同平臺的原生應用程序。適用于對于三端述求高,性能要求也高的場景。由于設計之初是面向小程序的,所以規(guī)范上對ReactNative研發(fā)來說并不友好。
考慮到我們業(yè)務對于多端和性能的要求都很高,結合現(xiàn)有團隊技術儲備能力,所以選擇Taro多端同構技術方案。在本文中,我們會重點講述旅游事業(yè)部門票活動前端團隊和公共無線技術團隊合作將Taro技術棧與現(xiàn)有技術進行融合后,遇到的問題以及相應的解決方案。
三、Taro如何與現(xiàn)有技術融合
Taro提供的多端同構技術,在不需要考慮與現(xiàn)有技術棧的結合的前提下,是可以直接使用的。針對本身已有一套技術方案情況,就需要考慮如何將Taro與現(xiàn)有的App或Web技術進行融合。
Taro跨端方案是基于靜態(tài)編譯的解決方案,最終生成的是將源代碼編譯為目標代碼并打包成可執(zhí)行的文件。該文件既不能直接集成到業(yè)務方(攜程)RN、Web的框架中,也不能直接調用攜程提供的業(yè)務組件,如城市、日歷、支付等。因此,開發(fā)者需要對Taro進行適配后,才能解決與現(xiàn)有框架融合的問題。
如上圖,Taro的核心原理是在編譯構建時通過注入自定義配置,將原本的小程序組件和API替換為適應不同平臺的組件和API,從而實現(xiàn)多端能力。這樣一來,業(yè)務開發(fā)中可以使用相同的代碼來適配不同的終端,消除多端開發(fā)中的差異。
3.1 融合App(與攜程React Native技術融合)
1)在Taro的配置文件中,注入自定義plugins插件
2)通過Metro打包配置,進行別名替換(原有的taro引用替換成新的RN路徑)
3)抹平Taro的組件和APIs方法
Text組件
頁面跳轉API
按照以上步驟,并且結合ReactNative的腳手架,就可以運行起來。
3.2 融合Web(與攜程NFES技術融合)
Taro同構技術已在Web端的非SSR和SSR模式。SSR模式是以NextJS框架未基礎的,通過提供編譯插件tarojs-plugin-platform-nextjs來支持。但由于這個編譯插件并不支持基于NextJS技術擴展的Web框架或其它Web框架,所以需利用Taro腳手架中開放的編譯能力,在構建時通過babel插件將APIs和組件庫替換為支持服務端同構的版本,同時生成適配當前框架的目錄及項目配置,使得Taro具備轉換為對應Web框架的能力,具體參考如下步驟:
1)同RN,注入自定義H5 plugins插件
2)通過Webpack打包配置,進行別名替換
3)抹平Taro的組件和APIs方法
Text組件
頁面跳轉APIs
4)根據(jù)自身框架的調整路由、中間件等項目配置,以下是攜程NFES示例圖
按照以上步驟,并且結合自身Web的腳手架,就可以運行起來。
四、技術實踐
在解決好Taro多端框架與現(xiàn)有技術融合的問題之后,還需要進一步完善組件和API的豐富度,提升應用程序的性能,并解決CSS適配的問題,以實現(xiàn)降低開發(fā)成本和提升用戶體驗的目標。
4.1 組件庫與API
1) 組件和API豐富度
Taro多端同構技術的核心方案是通過抹平組件庫和API差異,實現(xiàn)跨端同構,從而使得性能和用戶體驗與獨立開發(fā)單一端的應用程序相一致。然而,這種方法的不足之處在于需要開發(fā)各端的組件庫和API,以與Taro小程序相對齊,這需要較大的初始成本。
Taro多端設計時已考慮到了降低研發(fā)人員首次投入的成本,所以提供對齊Taro小程序的組件庫和API,共計60多個。經(jīng)過實踐驗證,已滿足大部分常用的業(yè)務需求。
除了已提供的組件和API外,仍舊需要開發(fā)面向業(yè)務的擴展組件和API,例如,彈層、折疊、日歷和城市選擇等組件以及支付、登錄等(如上圖)。大部分組件只需要在官方提供組件上做二次封裝,研發(fā)成本不大。
2) 多端組件和API差異性
多端組件和API在不同平臺上可能存在一些差異,無法完全抹平。每個平臺有自己的特性和限制,因此在開發(fā)多端應用時,需要對這些差異進行適配和處理。
比如在動畫實現(xiàn)方面就存在不同平臺之間的差異。在ReactNative中,只能使用Animation組件來實現(xiàn)動畫效果,在小程序和Web端是使用CSS樣式來實現(xiàn)動畫效果,為了盡量保持多端一致性,將動畫實現(xiàn)封裝成一個統(tǒng)一的組件,以便在不同平臺上使用。封裝后的動畫組件,在RN端調用的是Animation組件,在小程序和Web端則使用組件內通過Js添加Css樣式來實現(xiàn)動畫。這種方式解決了動畫實現(xiàn)的差異性,使得開發(fā)人員可以通過使用統(tǒng)一的接口來調用動畫效果,無需過多關注不同平臺的具體實現(xiàn)細節(jié)。
把以上遇到抹平問題,可以歸納為以下3類情況:
情況說明 | 解決方案 | 例如 |
A,B端都有此功能但差異不大 | 抹平差異 | input、路由跳轉等 |
A,B端都有此功能但差異很大 | 抹平差異 | 動畫組件封裝成統(tǒng)一API |
A端有此功能但B端沒有 | 降級抹平差異或差異抹平 | 差異抹平:各端實現(xiàn)各端,如RN使用Flatlist,其它端使用scrollview 降級抹平:有的顯示,沒有的不顯示,如頭部導航欄不存在小程序中 |
4.2 CSS適配
CSS的跨端支持性是較弱的,受限于ReactNative的平臺限制,所以支持并不友好。
ReactNative不支持CSS樣式的嵌套。只能將樣式拆分成多個獨立的對象,并通過StyleSheet.flatten方法將它們合并成一個對象,從而實現(xiàn)在一個層級節(jié)點上設置獨立樣式。目前只能通過差異抹平適配多端方法,犧牲其他端CSS靈活性。
ReactNative不支持CSS中的偽元素選擇器。如::before和::after,因為它沒有DOM元素并且不支持這些選擇器。可以通過添加HTML節(jié)點來適應選擇器寫法。
上述的寫法限制了多端開發(fā)的效率,但并不影響產(chǎn)品的功能實現(xiàn)。另外一些樣式等問題,大部分可以使用Babel插件(如rn-style-transformer)來抹平。
平臺默認屬性差異
屬性 | ios-rn | android-rn | web | 小程序 |
fontSize | 14 | 16 | 16 | 16 |
color | #000 | #777 | #000 | #000 |
margin | 0 | 0 | 8 | 0 |
padding | 0 | 0 | 1 | 0 |
平臺屬性支持差異
屬性 | ios-rn | android-rn | web | 小程序 |
background | 不支持 | 不支持 | 支持 | 支持 |
position:fixed | 不支持 | 不支持 | 支持 | 支持 |
textIndent:number | 不支持 | 不支持 | 支持 | 支持 |
dashed | 不支持 | 不支持 | 支持 | 支持 |
4.3 性能
Taro由于采用的是靜態(tài)編譯時生成平臺代碼,所以性能優(yōu)于動態(tài)編譯時生成的方式。在App端性能和原生RN性能相當,但是在Web端會將Dom節(jié)點替換為Web Component,而Web Component的渲染能力相對于原生組件較低。因此,如果在轉換過程中,如果存在大量Web Component,會導致頁面渲染的變慢。在電腦型號為MacBook Pro(14英寸,2021年),瀏覽器型號為chrome,瀏覽器版本為113.0.5672.63(正式版本)(arm64)的測試條件下,以taro-view-core(View)組件為例,重復渲染2000次,總耗時大約在123ms。如果換成div重復渲染2000次耗時大約在17ms,大概相差7倍左右,實驗截圖如下:
Web Component耗時:
原生div耗時:
從以上實驗可以得出,不要直接使用 Taro 提供的 View 和 Text 等組件,而是在 Web 原生組件上再包一層具備 Taro 功能的組件。
五、 適用場景和成本
5.1 View層同構
根據(jù)交互和產(chǎn)品設計的需要,對于App、H5、小程序交互方式相似度大于70%建議可以采用一套View,差異部分可以用Taro工程提供的文件擴展名方式實現(xiàn)各自的差異部分。
由于 PC 端的交互方式差異較大,因此通常需要編寫兩套View組件,這樣做比較合適。
5.2 多端同構適用場景
多端同構適用于需要在多個平臺上提供相同功能的應用程序,達到提高開發(fā)效率和用戶體驗的目的。
不適用于對性能要求較高以及高度依賴平臺的專屬特性的應用程序,比如基于canvas制作的游戲,對于不適用場景且多個平臺都需要支持的話,只能各自實現(xiàn)各自效果。
5.3 多端同構的成本
盡管多端同構技術可以減少開發(fā)的成本,但不同平臺之間仍存在樣式和API的差異,需要研發(fā)人員進行適配和補充。實際各端的研發(fā)成本對比可參考下表:
研發(fā)成本 | 多端同構后 | 備注 | |
App | 1 | 0.2 | |
H5 | 1 | 0.2 | |
小程序 | 1 | 1.2 | 先開發(fā)的平臺 |
PC | 1 | 0.4 | |
總計 | 4 | 2.2 |
隨著開發(fā)經(jīng)驗的積累和組件的豐富化,研發(fā)和測試成本也會進一步降低。
學習成本:多端同構開發(fā)需要研發(fā)人員具備跨端開發(fā)的能力和經(jīng)驗,需要了解各個平臺的特性和差異,同時還需要關注代碼的性能、可維護性和可擴展性等方面。我們可以通過多種培訓和分享來提高他們的能力和技能。
測試成本:在多端同構的開發(fā)模式下,如果不慎改錯一端會影響到所有端,所以測試成本會增加。測試范圍更廣,測試時間也會更長,因此測試成本也會相應地增加。另外,由于不同平臺之間的差異,測試人員需要具備跨平臺測試的能力,這也會對測試人員的研發(fā)能力提出更高的要求。為了解決這些問題,可以普及 UT(單元測試)和 AT(自動化測試),這可以降低測試成本,提高測試效率。
生產(chǎn)穩(wěn)定性:因為多端同構技術采用的是統(tǒng)一的代碼邏輯和組件封裝,一旦出現(xiàn)問題,多個平臺都會受到影響。因此,在開發(fā)過程中需要進行嚴謹?shù)臏y試和質量控制,以確保代碼的穩(wěn)定性和可靠性。
六、總結與展望
本文介紹的是通過使用Taro實現(xiàn)多端同構,在跨多平臺業(yè)務場景中降低研發(fā)成本,提升用戶體驗。通過使用同一開發(fā)語言和代碼框架,實現(xiàn)在不同端上復用代碼,達到統(tǒng)一業(yè)務邏輯的目的。
可以預見在不久的將來,無論是基于業(yè)務需求還是技術實踐與創(chuàng)新,都將出現(xiàn)更多的解決方案,使得多端開發(fā)之路變得更加平坦。同時,這套方案將成為公司主推的多端框架。