《2018年攜程大規模應用React+Native的工程化實踐.pdf》由會員分享,可在線閱讀,更多相關《2018年攜程大規模應用React+Native的工程化實踐.pdf(42頁珍藏版)》請在三個皮匠報告上搜索。
1、攜程大規模應用React Native的工程化實踐攜程旅行網Topic面臨的挑戰和方案的選擇ReactNative在攜程的使用現狀CRN框架的優化我們的經驗與實踐總結與未來展望為什么會使用RN開發成本動態更新社區資源相對較低支持動態更新相對成熟,社區活躍包大小性能體驗占用AppSize小用戶體驗佳現狀 業務廣泛接入 攜程旅行App,線上70+RN業務模塊 大量首頁入口使用RN開發 PV占比超過H5 Hybrid 集團內多App已接入使用?現狀 業務深度使用 核心業務、全流程使用Native轉RNHybrid轉RN 復雜業務高(火車票)710個JavaScript模塊100個Page代碼7z壓縮
2、后600KBCRN框架介紹運行頁面性能監控穩定性優化Lazy RequireBundle拆分文檔組件開發代碼倉庫動態打包配置發布系統及監控運維CLI工具線上錯誤監控框架預加載CRN是基于RN定制,以實現開發友好、運行穩定高效、運維可監控的大前端開發框架。開發 CLI和文檔支持 CLI和文檔開發 組件擴展支持 70+API和UI組件支持 重寫fetch、listview等組件 擴展ScrollView組件 跨容器(Native、Hybrid、RN)通訊支持 組件開發原則,RN優先,Native兜底開發 Event機制 Event機制解決多端通訊問題Event.addEventListener(n
3、ame,callback)Event.removeEventListener(name)Event.sendEvent(name,data)基于Notification實現開發 統一Storage 統一Storage提供Storage.load(params,callback)Storage.remove(params)Storage.save(params)設計說明存取支持domain區分不同業務存取expireDate支持存取內置加解密支持開發 CRN Page模型 CRN Page 模型CRN 容器:包含ReactRootView業務Page繼承自CRN Page基類CRN容器:CRNV
4、iewController/CRNActivityCRNPageACRNPageBCRNPageCCRN App開發 Page生命周期擴展 CRN Page生命周期擴展所有CRN頁面繼承同一Page基類解決和Native/Hybrid/其它RN業務模塊頁面切換無回調問題解決App前后臺切換無回調問題同一CRN容器內不同Page間切換pageWillAppearpageDidAppearpageWillDisappearpageDidDisappearCRN新增cmpDidMountcmpWillUpdatecmpDidUpdatecmpWillUnmount常規組件生命周期cmpWillMou
5、nt運行 Bundle拆分和Require優化為什么要拆分簡單HelloWorld項目release打包520KB,壓縮后147KB大量業務模塊上線,size占用是問題為何要改造Require后臺預加載提升首屏渲染時間支持動態按需加載運行 Bundle打包文件結構1.Global Define/Require.2.Module define.3.Require()Bundle結構抽象 官方命令打包出的Bundle運行 Bundle代碼執行順序1.Global Define/Require.2.Module define.3.Require()1.Global Define/Require.3.
6、Require().2.Module define代碼執行順序 官方命令打包出的Bundle運行 Android Unbundle打包 RN Android Unbundle打包所有模塊都打包成獨立文件運行 CRN Bundle拆分 CRN打包方案,合并common官方命令打包出的bundle運行 Bundle拆分之后的加載CRN Bundle拆分之后執行過程框架JavaScriptA目錄ReactInstanceManager/Bridge(JavaScript Core)RequireLoad業務代碼資源B目錄運行 Bundle拆分之后的加載CRN Native Require實現官方An
7、droid在unbundle打包的js-modules目錄中查找執行官方iOS在一個preparePack打包的二進制bundle中查找執行CRN改造iOS平臺的nativeRequire,支持從磁盤目錄查找和執行模塊運行 JS模塊加載Define 和 Require加載JS模塊運行 預加載RN業務加載的耗時分布 預加載Require是代碼真正執行的點Require耗時長后臺Require框架代碼,提速首屏渲染運行 預加載提速首屏加載 首屏加載提速后臺創建instance(JavaScriptCore實例)加載框架代碼Instance被使用之后,創建新的首屏加載性能相較官方提升約45%2833
8、5838015119418584611151109389668482020040060080010001200?A?)?(?(?(?(?數據基于RN0.30,iPhone6Sony Xperia多次測試后臺創建JSC執行框架代碼后臺創建JSC執行框架代碼后臺創建JSC執行框架代碼進入業務A僅執行業務代碼進入業務B僅執行業務代碼Instance(JSC)預創建流程運行 業務復雜度增加導致的問題簡單頁面,JS模塊少全業務使用,JS模塊多,首屏加載依舊緩慢運行 業務復雜度增加導致的問題 首屏加載慢問題重現業務復雜度增加,代碼量劇增import代碼在打包過程會變成require 解決方案進入業務時,盡
9、可能少執行requireimport*from引用模塊Require(id)執行模塊代碼Define(path,id)定義模塊import模塊的內部處理流程運行 LazyRequire方案 CRN LazyRequire實現開發階段,LazyRequire等價于require接入階段,CRN Page 只需替換import打包階段,Babel插件將lazyRequire參數從path替換成模塊ID運行階段,Page在切換時候,框架loadLazyRequire的內部實現運行 LazyRequire方案 線上數據復雜業務首屏加載提升明顯(右圖)徹底解決了復雜業務使用CRN的問題548345405
10、1801751690100200300400500600123?(?)?)?數據基于RN0.41,iPhone Simulator多次測試運行 其它Require優化方案 inlineRequire方案定義全局變量,使用時,require并賦值 ES5構造函數ReactNative內部組件以此方式導出推薦使用這種方式穩定性優化 iOS 框架層設置錯誤處理handler不設置在生產環境會crash記錄錯誤來源 業務層出錯顯示出錯浮層,支持重試穩定性優化 Android JavaScript層DevSupportManager Native層NativeModuleCallExceptionHan
11、dlerSO加載優化頁面長時間加載不成功的優化穩定性優化 降級處理 優雅降級自動降級參數傳遞的風險降級策略定制 具體方案CRN原始URL:/rn_abc/index?pa=1&pb=2&px=x降級H5站點URL:http:/ 錯誤日志收集 錯誤日志收集系統實時上報錯誤JS/Native異常日志完整callstack展示可按照模塊名、版本過濾支持報警配置發布之后需關注數據走勢運維 性能統計 CRN性能統計系統按業務模塊,版本統計首屏時間加載耗時比例分布展示運維 發布增量包優化 Diff方案對zip包內部的每一項進行bsdiff,保留變化過的文件,然后7z壓縮 優化點充分利用CRN包格式優勢保留
12、業務模塊id的mapping,避免新增模塊而導致模塊id全亂的情況運維 發布增量包優化 線上數據線上22個CRN增量包,總計325KB,平均每個包15KB發布后一小時,新包使用率達97-98%實踐經驗 版本升級 組件依賴管理 CRN包的依賴管理 分平臺打包 導航欄的選擇CRN版本升級2016年6月2016年8月2017年2月2018年2月0.510.410.300.28CRN版本升級歷程CRN版本升級 升級流程 升級成本框架團隊成本2-3周業務升級一周完成 其它升級方案盡可能對業務簡單避免業務包做跨RN版本的發布升級頻率8-12個月/次框架框架團隊驗證團隊驗證業務配合升級業務配合升級發布系統確
13、認發布系統確認組件依賴管理 組件倉庫CRN 倉庫:常用組件,必需依賴CRN_Ext倉庫:獨立組件,按需依賴內網npm倉庫:第三方模塊,按需CRN相關倉庫,使用git分支依賴 版本管理固定版本,避免使用、*構建過程檢查依賴的版本CRN包的依賴管理 依賴規則業務包只依賴框架包業務包之間平行,不允許依賴 其它發布高到達率情況下,不提供強制更新功能不同業務包之間跳轉,會觸發最新增量包下載分平臺打包 原方案CRN框架包分開打包業務包共用,以iOS平臺打包正常運行一年多 問題暴露平臺獨立組件,打包產物不一致分2次打包,打包之后merge打包產物Android優先在js-diffs中查找模塊導航欄的選擇 官
14、方Navigator0.44開始廢棄復雜頁面切換時,卡頓明顯CRN使用該方案,優化了頁面切換動化 第三方ReactNavigator(推薦)純JavaScript實現,性能優秀,功能強大頁面切換使用animated動畫 第三方ReactNativeNavigatorNative實現,跨平臺兼容性有些問題NavigatorCRN優化總結CRN框架對RN進行改造優化,解決了性能和穩定性兩大核心問題,且在業務團隊廣泛深度使用CRNWEB基本成熟,已有10個左右業務模塊接入,未來會大力推廣,CRN(WEB)一體化的解決方案,進一步降低開發維護成本持續優化RN性能和穩定性,分享CRN的優化思路和方案,適時開源部分組件和方案