偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

從47%到80%,攜程酒店APP流暢度提升實踐

移動開發(fā) 移動應用
APP性能提升一直是研發(fā)團隊永恒的主題。在進行APP性能優(yōu)化實踐中,除了性能技術方案本身外,還會面臨兩方面問題。

作者 | Jin,攜程高級研發(fā)經理,專注移動技術開發(fā);Dan,攜程測試開發(fā)經理,關注數據挖掘以及數據在系統(tǒng)質量提升中的應用;Lanbo,攜程軟件技術專家,專注移動技術開發(fā)。

一、背景

APP性能提升一直是研發(fā)團隊永恒的主題。在進行APP性能優(yōu)化實踐中,除了性能技術方案本身外,還會面臨兩方面問題:第一,APP的性能優(yōu)化,不具有持續(xù)性,往往經過一段時間優(yōu)化實踐,效果明顯,但是隨著后續(xù)需求迭代和代碼變更,APP性能很難維持在一個較好的水平上;第二,APP性能改善提升,缺乏一套科學量化手段進行衡量。

?引?管理學?師彼得?德魯克的?句話:If you can’t measure it, you can’t improve it,如果你?法度量它,你就?法改進它?;诖?,攜程酒店前端APP團隊進行了深入思考和探索,希望通過量化,治理,監(jiān)控三方面手段,持續(xù)改善APP性能和用戶體驗。

二、流暢度指標定義

流暢度,簡單說就是度量用戶使用APP體驗的一部分,它是用戶快速、無阻礙使用APP的一項體驗指標。主要包括三方面內容:穩(wěn)、快、質。穩(wěn)的含義是用戶在打開具體一個頁面時,沒有出現白屏、崩潰、閃動等。快的含義是頁面打開很快,用戶在頁面進行交互時,操作流暢自然。質的含義,是在瀏覽頁面時,沒有無故的彈窗攔截,打斷用戶的操作。如下圖所示:

基于以上理論基礎,APP中白屏,崩潰閃退,加載慢,卡頓,閃動,報錯,都是用戶在感知層面形成不流暢的因素。于是我們提出了流暢率量化指標,把用戶頁面PV以及用戶在頁面觸發(fā)的二次加載次數之和,定義為流暢率的分母,也就是樣本總量,如下公式:

  • 樣本量 = 頁面pv+二次加載數

把頁面慢加載/頁面卡頓/圖片/視頻慢加載PV去重后數量,加上頁面出現的崩潰,滑動卡頓,圖片/視頻加載失敗,全局彈窗報錯,輸入失焦,按鈕點擊無效,二次加載失敗,二次加載慢等異常情況之和定義為不流暢因子數。那么流暢率的公式定義為:

  • 流暢率 = (樣本量-不流暢因子數)/ 樣本量

2.1 頁面可交互加載時長

頁面可交互加載時長,是頁面渲染繪制時間疊加網絡服務的請求響應時間,可以簡單用下面公式表示:

  • 頁面可交互加載時長(TTI)= 頁面本地渲染時長+服務網絡加載時長

2.2 頁面可交互加載時長采集原理

在我們的核心頁面中,都包含了Text控件,可以通過掃描頁面中特定區(qū)域內的文本來確定用戶可交互時間。我們的技術棧大體上分為Flutter和Ctrip React Native,以下分別介紹加載時長采集原理。

2.2.1 Flutter頁面可交互加載時長采集原理?

在Flutter中,最終的UI樹其實是由一個個獨立的Element節(jié)點構成。UI從創(chuàng)建到渲染的大體流程如下:

根據Widget生成Element,然后創(chuàng)建相應的RenderObject并關聯(lián)到Element.renderObject屬性上,最后再通過RenderObject來完成布局排列和繪制。如下圖如所示:

所以可以從根節(jié)點開始遍歷Element,直到找到掃描窗口內的Text組件且組件的內容不為空,即可判定頁面TTI檢測成功,Flutter提供如下接口支持Element遍歷:

voidvisitChildElements(ElementVisitor visitor)?

2.2.2 Ctrip React Native頁面可交互加載時長采集原理?

我們知道,ReactNative最終是由Native組件來渲染的,在iOS/Android中可通過從根View從View樹中遞歸查找Text文本控件,來獲取頁面內文內的內容,去掉頁面頂部固定靜態(tài)展示和底部靜態(tài)展示區(qū)域之外,掃描到的文本數量大于1個,我們就認為頁面TTI檢測成功了。

2.3 渲染卡頓和幀率

Google對卡頓定義:界面呈現是指從應用生成幀并將其顯示在屏幕上的動作。要確保用戶能夠流暢地與應用互動,應用呈現每幀的時間不應超過 16ms,以達到每秒 60 幀的呈現速度。如果應用存在界面呈現緩慢的問題,系統(tǒng)會不得不跳過一些幀,這會導致用戶感覺應用不流暢,我們將這種情況稱為卡頓。

2.3.1 卡頓標準?

判斷 APP 是否出現卡頓,應該從APP類型是普通應用還是游戲應用出發(fā),不同類型APP,對應不同的卡頓標準。針對普通類型應用,可以參考借鑒Google 的 Android Vitals 性能指標,針對游戲,可以參考借鑒騰訊的 PrefDog 性能指標。因為我們APP是普通應用,簡單的介紹下Google Vitals 的卡頓定義。

GoogleVitals把卡頓分為了兩類:

第一類是呈現速度緩慢:在呈現速度緩慢的幀數較多的頁面,當超過 50% 的幀呈現時間超過 16ms 毫秒時,用戶感官明顯卡頓。

第二類是幀凍結:幀凍結的繪制耗時超過 700ms,為嚴重卡頓問題。

另外,要注意的是,FPS的高低和卡頓沒有必然關系,幀率 FPS 高并不能反映流暢或不卡頓。比如:FPS 為 50 幀,前 200ms 渲染一幀,后 800ms 渲染 49 幀,雖然幀率50,但依然覺得非??D。同時幀率 FPS 低,并不代表卡頓,比如無卡頓時均勻 FPS 為 15 幀。

2.3.2 卡頓量化?

當了解卡頓的標準以及原理之后,可以得出結論,只有丟幀情況才能準確判斷是否卡頓。

Flutter官方提供一套基于SchedulerBinding.addTimingsCallback回調實現的實時幀數據的監(jiān)控。當flutter 頁面有視圖繪制刷新時, 系統(tǒng)吐出一串 FrameTiming 數據 ,FrameTiming的數據結構如下:

vsyncStart,
buildStart,
buildFinish,
rasterStart,
rasterFinish

vsyncStart變量表示當前幀繪制的起始時間,buildStart/buildFinish表示WidgetTree的build時間,rasterStart/rasterFinsih表示上屏的光柵化時間,那么一幀的總渲染時間,可以利用下面公式得到:

totalSpan=>rasterFinish  - syncStart

對應Google Android Vitals卡頓的標準:如果一幀totalSpan > 700ms,認為發(fā)生了幀凍結,產生了比較嚴重的卡頓;如果1s內,有超過30次的幀的繪制時間totalSpan> 16ms,產生了呈現速度緩慢。

三、流暢度監(jiān)控方案

在流暢度監(jiān)控體系中,對于不流暢感知因子,進行單項分析及挖掘,旨在在迭代優(yōu)化的同時,維持或提升已有的用戶體驗。

監(jiān)控體系的搭建,分為現狀及優(yōu)化方向挖掘、監(jiān)控指標依賴數據補齊、多維度的數據監(jiān)控、指標監(jiān)測預警。

監(jiān)控搭建前期會對于APP現有的性能現狀進行分析,挖掘可優(yōu)化的方向,初步獲得優(yōu)化所帶來的預計收益、影響的用戶數等信息。如:預計使用預加載的方式,來降低用戶的慢加載率,通過各場景的不同用戶操作分析,以及目前客戶端及服務端技術實現的現狀(酒店主服務返回報文大小統(tǒng)計、酒店詳情純前端渲染時間等),來確定慢加載的覆蓋面、觸發(fā)時機,以達到更優(yōu)的效果。

接下來,針對流暢度優(yōu)化的業(yè)務、技改上線的同時,補充對應的監(jiān)測場景埋點,以支撐流暢度量化衡量的數據,為后續(xù)的監(jiān)控及預警,奠定堅實的基石。

監(jiān)控體系的核心是大盤及多維度監(jiān)控的鋪開,大盤數據(如下圖所示),能快速宏觀的了解用戶預訂體驗,明確流暢度提升的進度;而通過各種維度的數據表,即可以找到提升目標,也能監(jiān)控優(yōu)化效果。

在實際監(jiān)控中,會針對不同的指標,設計不同的監(jiān)控標準,如:慢加載、白屏、奔潰、卡頓等系統(tǒng)因素,除了大盤指標外,還增加了各指標影響占比、酒店主頁面的報錯率趨勢、版本對比趨勢、報錯機型top分布等。

對于業(yè)務場景比較重的因素,結合業(yè)務數據進行分桶等方式的監(jiān)控,如:詳情頁房型數量關聯(lián)TTI耗時分布、單酒店crash數據等。并與AB實驗系統(tǒng)打通,業(yè)務、技改類需求都可以在AB系統(tǒng)中配置流暢度觀測指標,比對業(yè)務或技改需求對流暢度的指標影響,作為實驗是否通過的考量指標。

對于各項指標進行單項波動預警,做到有上升就預警、有新增就預警,做到不放過、不遺漏。如:填寫頁業(yè)務報錯量(可訂服務、提交訂單、失焦錯誤數),除了對各類報錯率趨勢進行監(jiān)控外,還會綜合實際用戶流量,區(qū)分單項業(yè)務報錯的流量大小進行預警,且對拆分多維度(單用戶、單房型等)觸發(fā)次數,便于尋找到有特性的badcase,快速定位用戶遇到的問題,挖掘更多的業(yè)務優(yōu)化點。

四、流暢度治理實踐

在APP流暢度治理上,主要從頁面啟動加載速度,長列表卡頓治理,頁面加載閃動三個方面進行了諸多優(yōu)化實踐,這些優(yōu)化并沒有涉及高大上的底層引擎優(yōu)化技術,也沒有復雜的數學理論基礎,更沒有重復造輪子。我們堅持以數據為導向,用數據驅動方案,用數據驗證方案,發(fā)現問題,提出解決方案,解決問題。

4.1 頁面加載速度優(yōu)化

在頁面加載速度優(yōu)化上,我們從2021年8月份開始進行迭代優(yōu)化至今,酒店預訂流程頁面的慢加載率從初始值的42.90%降低至現階段的8.05%。

在頁面啟動加載速度優(yōu)化上,一般都會采用數據預獲取方案,原理是在上一個頁面提前獲取服務數據,在用戶跳轉到當前頁面時,直接從緩存獲取,節(jié)省了數據的網絡傳輸時間,達到快速展示當前頁面內容的效果。目前在酒店核心預訂流程,都運用了數據預加載技術,如下圖所示:

結合酒店業(yè)務特點,數據預加載需要考慮幾個方面問題:第一,酒店預訂流程頁面PV量較高,酒店列表和詳情頁PV在千萬級別。需要考慮數據預加載的時機,避免服務的資源浪費;第二,酒店列表、詳情、訂單填寫頁都有價格信息,價格信息對用戶來說是動態(tài)信息,實時都有變價可能,所以需要考慮數據預加載的緩存策略,避免因為價格的前后不一致造成用戶誤解。?

4.2 Flutter服務通道優(yōu)化

攜程APP采用的私有服務協(xié)議,目前發(fā)服務的動作還是在Native代碼上,而酒店的核心頁面已經轉到了Flutter上。通過Flutter框架提供的通道技術,Native到Flutter的數據傳輸通道需要對數據做一次額外的序列化及反序列化的傳輸,同時傳輸的過程比較耗時,會阻塞UI的渲染主線程,對頁面的加載會造成明顯的影響。我們檢測到這個環(huán)節(jié)之后,和公司的框架團隊一起對Flutter的底層框架進行了改造,可以實現數據流直接的透傳,同時不阻塞UI主線程,性能得到了極大的提升。

優(yōu)化前,通過服務返回的數據流傳遞到Flutter使用,整個過程要經歷以下4步:

  • PB反序列化
  • Reponse到JsonString的編碼
  • JsonString到Flutter通道傳輸
  •  JsonString到Reponse的解碼

整個過程鏈路長,數據傳輸量大,效率低,影響到頁面加載性能,如下圖所示:

?改造后,通過服務返回的數據流,直接傳輸到Flutter側,在Flutter直接進行PB的反序列化,傳輸性能得到極大提升。

  • PB的數據流Flutter通道傳輸
  • PB反序列化到Reponse

整個過程鏈路短,數據傳輸量小,效率高,如下圖所示:

4.3 卡頓問題分析和定位

在 Flutter 中,可以利用性能圖層(Performance Overlay),來分析渲染卡頓問題。如果 UI 產生了卡頓,它可以輔助我們分析并找到原因。如下圖所示:

?GPU線程的繪制性能情況在圖表的上方,CPU UI線程的繪制情況顯示在圖表下方,藍色垂線表示已渲染的幀,綠色色垂線代表的是當前幀。

為了保持60Hz 刷新頻率,每一幀耗時都應該小于 16ms(1/60 秒)。如果其中有一幀處理時間過長,就會導致界面卡頓,圖表中就會展示出一個紅色豎條。下圖演示了應用出現渲染和繪制耗時的情況下,性能圖層的展示樣式:

如果紅色豎條出現在 GPU 線程圖表,意味著渲染的圖形太復雜,導致無法快速渲染;而如果是出現在了 UI 線程圖表,則表示 Dart 代碼消耗了大量資源,需要優(yōu)化代碼執(zhí)行時間。

另外我們可以借助于AS里面的Flutter Performance工具查看Flutter頁面的rendering性能問題,里面有個很有用的功能Widget rebuild stats,它統(tǒng)計在渲染UI的時候,各個widget rebuild數量情況,可以輔助我們很快的定位存在問題的widget,如下圖:

UI CPU線程問題定位

UI線程問題實際就是應用性能瓶頸。比如在Widget構建時,在 build 方法中使用了一些復雜運算,或是在Root  Isolate 中進行了耗時的同步操作(比如IO)。這些都會明顯增加 CPU 處理時間,造成卡頓。

我們可以使用 Flutter 提供的 Performance 工具,來記錄應用的執(zhí)行軌跡。Performance 是一個強大的性能分析工具,能夠以時間軸的方式展示 CPU 的調用棧和執(zhí)行時間,去檢查代碼中可疑的方法調用。在點擊了Flutter Performance工具欄中的“Open DevTools”按鈕之后,系統(tǒng)會自動打開 Dart DevTools 的網頁,我們就可以開始分析代碼中的性能問題了。

GPU問題定位

GPU 問題主要集中在底層渲染耗時上。有時候 Widget 樹雖然構造起來容易,但在 GPU 線程下的渲染卻很耗時。涉及 Widget 裁剪、蒙層這類多視圖疊加渲染,或是由于缺少緩存導致靜態(tài)圖像的反復繪制,都會明顯拖慢 GPU 的渲染速度可以使用性能圖層提供的兩項參數,負責檢查多視圖疊加的視圖渲染開關checkerboardOffscreenLayers和負責檢查緩存的圖像開關checkerboardRasterCacheImages。

checkerboardOffscreenLayers

多視圖疊加通常會用到 Canvas 里的 savaLayer 方法,這個方法在實現一些特定的效果(比如半透明)時非常有用,但由于其底層實現會在 GPU 渲染上涉及多圖層的反復繪制,因此會帶來較大的性能問題。對于 saveLayer方法使用情況的檢查,我們只要在 MaterialApp 的初始化方法中,將 checkerboardOffscreenLayers 開關設置為 true,分析工具就會自動幫我們檢測多視圖疊加的情況了,使用了 saveLayer 的 Widget 會自動顯示為棋盤格式,并隨著頁面刷新而閃爍。

不過,saveLayer 是一個較為底層的繪制方法,因此我們一般不會直接使用它,而是會通過一些功能性 Widget,在涉及需要剪切或半透明蒙層的場景中間接地使用。所以一旦遇到這種情況,我們需要思考一下是否一定要這么做,能不能通過其他方式來實現。如下圖所示,因為詳情頭部bar用到高斯模糊,同時使用ClipRRect裁切圓角,ClipRRect會調到savelayer接口,所以該部分產生閃爍。

checkerboardRasterCacheImages

從資源的角度看,另一類非常消耗性能的操作是,渲染圖像。這是因為圖像的渲染涉及 I/O、GPU 存儲,以及不同通道的數據格式轉換,因此渲染過程的構建需要消耗大量資源。

為了緩解 GPU 的壓力,Flutter 提供了多層次的緩存快照,這樣 Widget 重建時就無需重新繪制靜態(tài)圖像了。與檢查多視圖疊加渲染的checkerboardOffscreenLayers 參數類似,Flutter 也提供了檢查緩存圖像的開關 checkerboardRasterCacheImages,來檢測在界面重繪時頻繁閃爍的圖像(即沒有靜態(tài)緩存)。

我們可以把需要靜態(tài)緩存的圖像加到 RepaintBoundary 中,RepaintBoundary 可以確定 Widget 樹的重繪邊界,如果圖像足夠復雜,Flutter 引擎會自動將其緩存,避免重復刷新。當然,因為緩存資源有限,如果引擎認為圖像不夠復雜,也可能會忽RepaintBoundary。

4.4 Ctrip React Native(簡稱CRN)頁面的優(yōu)化

下圖是基本的CRN頁面的加載流程,各個階段的優(yōu)化之前已有文章進行過描述,如容器預加載,Bundle拆分,容器復用,框架預加載等等在容器層面做了優(yōu)化。

以酒店訂單填寫頁為例,此頁面采用了CRN的架構,在已有各類容器層面和框架層面的優(yōu)化之后,我們重點對頁面內重繪做了治理,并將重繪治理做到了極致,主要涉及到上圖中的“5. 首屏首次渲染”和“7. 首屏二次渲染”。

4.4.1 頁面內Action整合?

此頁面采用Redux架構,前期經歷了幾年的粗放式開發(fā)之后,頁面內的action眾多(Action通過異步事件的方式觸發(fā)狀態(tài)管理的改變,從而達到頁面重繪的目的,可以參考Redux的 Action-Reducer-Store模式)。?

優(yōu)化前,如下圖,頁面初始化/開始加載/加載中/加載完成,均觸發(fā)多個action,由于action是異步的,每個數據處理模塊都有一些耗時和異步,加載完成后頁面可能已經刷新,此處有可能展示了未處理完成的數據,等后續(xù)action執(zhí)行完成后,頁面會再次刷新。

由于有數據變化,頁面內元素可能會有變化,從而對用戶而言,頁面產生了抖動,同時也會加大JS<=>Native的通信量,頁面內元素的不斷變化,也會不斷刷新native中的渲染樹,消耗大量CPU時間,進而導致頁面不流暢,耗時較長。

針對上述情況,我們對頁面內的Action做了整合:

  • 靜態(tài)數據避免使用action
  • 觸發(fā)時機相同的action盡量合并
  • 非必要數據延遲加載
  • 多層action的更新進行整合

整合后,頁面內的action大致如下:基本只有頁面初始化,主服務返回,以及后續(xù)子服務的action了。

在此過程中我們采用了redux-logger的方式來監(jiān)控action,同時采用MessageQueue的方式來監(jiān)控action變化觸發(fā)刷新的情況,如下圖:

4.4.2 控件重繪治理?

為了更好的控制控件重繪的頻率,我們對控件做了以下拆分:

  • 盡量的拆細組件
  • 降低單文件的復雜度
  • 組件復用更加方便
  • 依賴數據變少,狀態(tài)更好管理
  • 局部更新數據不影響其他組件
  • 使用Fragments避免多層嵌套

拆分之后組件顆粒度更小,弱業(yè)務相關的采用了PureComponent,強業(yè)務組件采用Component+shouldComponentUpdate+自行比較屬性是否變化來避免組件的重繪。

通過上述方式的治理,進入填寫頁內已明顯感覺頁面比較輕,主服務返回后頁面立等可刷新,頁面的渲染速度大幅提升。

重繪治理我們采用了https://github.com/welldone-software/why-did-you-render的方案來檢測組件由于什么原因重繪,如下圖:

五、規(guī)劃和總結

整個APP流暢度治理中,從流暢率從初始47%提升到目前80%,頁面慢加載率從原來的45%降低到現在的8%,白屏率從1.9%降至現在的0.3%,主流程頁面控件閃動基本消除,APP性能及用戶體驗有了較明顯的提升。

回顧近半年中文酒店APP流暢度實踐,整個過程艱辛,也時刻伴隨著焦慮。流暢度每一點的進步都不是一蹴而就,輕易達成的。但對整個團隊,收獲滿滿,整個實踐過程中,我們對flutter工程架構做了整體升級,尤其是數據傳輸層改造,業(yè)務層邏輯收口等;數據的預加載方案,也從1.0版本升級到2.0版本。最重要的是,整個團隊形成了數據量化的思想意識和用戶視角出發(fā)去優(yōu)化和解決問題。

目前流暢度2.0的版本也已經落地實踐,2.0將更多的不流暢感知因子加入流暢度統(tǒng)計,如主服務的二次加載,地圖慢加載、圖片及視頻慢加載、圖片及視頻加載失敗、彈窗及提示信息等,從更多系統(tǒng)及業(yè)務層面來提升用戶的預訂體驗。

責任編輯:未麗燕 來源: 攜程技術
相關推薦

2022-07-08 09:38:27

攜程酒店Flutter技術跨平臺整合

2024-09-10 16:09:58

2023-03-14 14:01:00

內存優(yōu)化

2022-12-14 10:09:44

研發(fā)效能

2024-03-22 15:09:32

2022-04-14 17:53:50

攜程AWS上云

2024-04-18 09:41:53

2022-10-21 10:40:08

攜程酒店MySQL慢查詢

2023-05-12 10:14:38

APP開發(fā)

2023-08-04 09:35:18

2023-11-24 09:44:07

數據攜程

2024-09-25 15:37:46

2022-07-15 12:58:02

鴻蒙攜程華為

2015-05-28 14:05:02

2022-05-13 09:27:55

Widget機票業(yè)務App

2017-07-06 19:57:11

AndroidMVP攜程酒店

2023-08-25 09:51:21

前端開發(fā)

2022-09-03 21:13:19

攜程供應商直連平臺

2022-07-15 09:20:17

性能優(yōu)化方案

2023-02-08 16:34:05

數據庫工具
點贊
收藏

51CTO技術棧公眾號