螞蟻金服是如何提升移動端體驗的?

「逆鋒起筆」,關注領取學習資源☞ 程序員進階必備資源免費送「各類技術!」 ☜文/數據體驗技術團隊-鳳蕭css

前言

不少企業都會特別注重本身產品的體驗,尤爲是移動端,那移動端的體驗爲何這麼重要?首先體驗自己就很重要,好的體驗帶給用戶的感覺是大相徑庭的,用戶選擇使用一個產品除了產品自己功能知足需求以外,還有一個更重要的緣由就是產品用起來「爽」,產品整個使用流程必然是溫馨天然,才能受到大衆喜好;此外,產品體驗已成爲市場競爭力之一,借用人人都是產品經理上面對體驗的論述:html

當技術已再也不是產品核心競爭力時,產品競爭的實質就是用戶體驗之爭。

若是產品不能讓用戶身心感到愉悅和溫馨,他們極可能會迅速使用其餘替代品,對於 toC 的產品尤其明顯,產品體驗糟糕必然會被市場淘汰。可是體驗是一個很龐大的話題,有不少方面會影響產品的體驗,如性能、UI、交互以及人性化的功能等等,本文拋磚引玉,只從技術層面的某幾個方面聊聊移動端的體驗優化,主要以 Android 爲切入點,IOS 大部分優化方向與 Android 相似。考慮到市面上絕大多數 APP 都是 Native+H5 相結合的應用,且本人項目中也大量使用 H5 頁面,所以將從 Native 端和 H5 端分別總結如何優化體驗。前端

Native 端體驗優化

一直在思考從技術層面上,Native 端什麼樣才稱得上是體驗佳的產品,有什麼評判標準,從過往經驗來看,我的以爲應該具有如下基本特質:android

  • 啓動速度要快
  • 交互流暢不卡頓
  • 有離線緩存
  • 支持弱網環境
  • 友好的用戶提示

做爲技術人須要重點把控的是前 4 點,第 5 點可能更多須要設計同窗介入,根據以往的經驗,能夠從如下幾個方面着手:啓動優化, 內存優化、 UI渲染優化、 網絡優化等,內存和 UI 渲染的優化主要針對卡頓問題,網絡優化中一個重點涉及的對象是緩存和弱網支持,每個方面均可以獨立成文進行專門的探索,本文只提供一些主流的優化思路供參考,不詳細展開。程序員

內存優化

雖然如今手機內存配置愈來愈好,可是內存依然是很吃緊的資源,由於系統對 APP 內存佔用有限制(具體大小依不一樣手機廠商而異)。內存的優化首先要避免大量的內存泄露,可使用leakcanary進行自動檢測,若要深刻分析,可使用 AndroidStudio 手動 dump 內存下來用MAT工具進行分析,發現其中潛在的內存泄露對象。其次是儘可能使用成熟的圖片開源框架,如Glide或者Picasso等展現圖片或者 Gif。內存優化除了注意 內存泄露,還要關注 內存的抖動,出現的緣由通常是大量頻繁的建立對象,致使頻繁觸發 GC,以至於 APP 使用卡頓,好比常見的場景是在自定義控件的 onDraw 方法建立對象,由於 onDraw 方法會頻繁調用,在 onDraw 方法中建立大對象會致使內存急劇增加,觸發 GC 致使卡頓。所以要儘可能避免在循環體中建立對象,能夠考慮使用對象池一次建立多處複用來規避內存抖動。web

UI 渲染優化

UI 渲染性能關係到 APP 的流暢度,16ms 內未能完成一次繪製就會出現掉幀,給人感受就是頁面卡頓,響應不及時。移動端上致使渲染性能降低的緣由和解決的通常套路:後端

佈局不合理

佈局要避免沒必要要嵌套,以使用 Hierarchy View 進行輔助查看佈局層級關係,來識別嵌套是否合理;同時要根據具體場景合理使用哪種佈局,如 RelativeLayout 不能濫用,對於複雜佈局能夠用 ConstaintLayout 代替;此外還可使用 viewstub 進行延遲加載佈局,用 merge 和 include 進行佈局複用。瀏覽器

過分繪製(overdraw)

過分繪製的出現是由於在重疊的層級結構中,一些不可見的部分由於某些緣由,如設置了背景色,也會出如今繪製操做中,致使這塊重疊區域的像素被屢次繪製,那明顯是浪費計算資源。可使用簡單方法識別過分繪製是否嚴重,在 Android 系統中開發主菜單裏面打開「調試 GPU 過分繪製」開關就能看到界面 UI 元素被不一樣的顏色塊標註(以下圖)watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=顏色從原色——藍色——綠色——粉色——紅色依次表明過分繪製嚴重程度從低到高,通常而言須要關心紅色的色塊 UI 元素,由於它有嚴重的過分繪製,是有優化空間的。個人通常解法是去掉佈局背後沒必要要的背景色,固然還有其餘因素會致使過分繪製,如包裝的自定義控件,自己由於不注意避免過分繪製的影響,在使用的時候就自帶嚴重的過分繪製問題。緩存

主線程有複雜耗時任務

主線程(UI 線程)不能有複雜耗時的計算任務,不然會致使 UI 無響應,卡頓,最終致使 ANR 的發生。服務器

網絡優化

  • 保證接口設計的合理性,必要時合併網絡請求,減小請求次數;
  • 網絡緩存,針對服務端返回的數據設置有效時間,在有效時間內不走網絡請求,減小流量消耗,能夠按照本身業務的特性自定義緩存的實現。在弱網或者是無網絡的狀況下,由於有緩存的支持,不至於 APP 打開一片空白,這給用戶更好的體驗。
  • 數據壓縮,如 Gzip 壓縮 request 和 response,減小網絡流量傳輸。

 

啓動優化

最主要的思路避免把所有的初始化任務放在 Application 中,可使用子線程或者懶加載的方式來處理初始化任務;另外常規套路是會給第一個 Activity 設置 theme,這樣打開 APP 瞬間看到不是白屏,給用戶的感受就是啓動速度獲得改善。

H5 頁面加速優化

移動互聯網時代,H5 頁面無處不在,幾乎 80%以上的 APP 都有 H5 頁面的影子,一份代碼多端運行且能快速部署的優點,讓 Hybrid 開發成爲不少 APP 的標配。雖然 Hybrid 在體驗上老是趕不上 Native 的體驗,甚至在處理不當的狀況下,糟糕的體驗會讓不少企業選擇使用其餘技術棧,可是 Hybrid 依然是不少公司使用的主流技術。我的認爲,在對頁面體驗沒有過高要求的狀況下,Hybrid 依然是當下最佳的開發方式。要實現較好的體驗,須要花費心思對 H5 頁面進行優化,我以爲有三個方向能夠進行優化:

  • 頁面啓動白屏時間
  • H5 頁面的交互體驗,如響應流暢度
  • 頁面渲染性能

本文只從影響體驗最重要的指標——白屏時間來聊聊如何進行優化,響應流暢度和頁面渲染性能由於缺少實踐經驗,這裏就不班門弄斧。

耗時拆解

先分析下在移動端從用戶點 H5 連接到頁面渲染完成展現給用戶,須要經歷的粗略過程,示意以下圖:watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

  • Webview 初始化
  • 下載靜態資源(html、js 和 css 等)
  • 數據請求
  • 渲染(解析、組裝、繪製)

這裏的渲染包含了 html、js、css 的解析,組裝成 Render Tree 以及最後的繪製。粗略的估算,能夠將耗時拆解爲:

總耗時(t) = Webview 初始化耗時(t1) + 下載靜態資源耗時(t2) + 數據請求耗時(t3) + 渲染耗時(t4)

其中 Webview 初始化、靜態資源加載以及數據請求佔用的耗時是比較多的,且這個耗時頁面必定處於白屏階段,如下對這三塊給出一些常規的優化方案,渲染的耗時優化本文不論述。

靜態資源的優化

靜態資源主要指 html,js 和 css 資源,對於單頁應用而言主要是 js 和 css,下圖是我參與的項目中頁面第一次打開時的靜態資源請求狀況(無瀏覽器緩存):watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=從頁面請求能夠看到,其中 1.js 的下載是比較耗時的,是應用比較核心的 js 文件,必須等待此文件下載完成,纔有可能繼續後面的頁面渲染。在幾乎零優化的狀況下能夠看到耗時接近 800ms,仍是有很大的優化空間的。下面從前端視角和客戶端視角來說解下靜態資源優化的思路。

前端視角

從前端的角度入手,能夠有如下幾個優化手段:

  • 資源壓縮,前端有成熟的工具能夠對生成的 js、css 等產物進行壓縮,如有必要能夠還考慮 gzip 壓縮,得到更大的壓縮比。
  • 資源請求合併,過多分散的資源包會產生過多的網絡請求,但也不能隨意合併,最佳的方式是按照頁面或者模塊進行劃分,並配置 async 屬性來異步加載 script 腳本。
  • 配置瀏覽器緩存,主要指強緩存和協商緩存,能夠大大減小網絡時延,減小服務器壓力。
  • 按需加載,對於單頁應用,若是在首頁就把整個站點的資源所有下載,實際上是不合理的,使用按需加載(懶加載)的方式能夠有效提升首頁性能。
  • 骨架屏也是在移動端頁面首屏優化的一個重要手段,在頁面數據未準備好的狀況,相比與枯燥的白屏頁面而言,展現骨架屏能給用戶一個好的感官體驗。可是如何生成質量高的骨架屏也是一個難點,須要綜合考慮 ROI 來選擇是否使用骨架屏。

客戶端視角

從客戶端角度入手,實際上是客戶端預加載靜態資源或者提早內置到手機本地,所以客戶端須要維護要加載到本地的靜態資源列表,當頁面打開時,攔截 webview 資源請求,根據資源 URL 路由到本地對應資源,這樣的速度是極快的。本身去實現該過程會比較繁瑣,上述過程的實現其實就是離線包方案,離線包機制能幫助作好靜態資源更新、管理、攔截、重定向以及異常鏈路,如支付寶的 nebula 容器自帶離線包解決方案。可是單個離線包不宜過大,通常 0-4M,對於較大應用有時候會突破這個限制,實際項目中將一些共用通用的框架資源(如 React、lodash、moment)提取出來,提早預置 APP 中來解決單個離線包大小限制,除此以外成熟的離線包方案自帶公共包機制,也能夠解決離線包過大的問題。下圖是通過優化後資源請求狀況, watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=能夠看到使用離線包外加預置公共資源方案以後,靜態資源的請求耗時直接降到 200ms 如下,幾乎全部的靜態資源在首次打開頁面就所有走本地存儲,優化效果仍是很明顯的。

數據請求優化

一些在瀏覽器中打開的 web 頁面可能不太注重數據請求的優化,在移動端,因爲追求極致體驗,每每數據請求也是有很大優化空間的。如下總結幾點數據請求的優化思路。

請求合併

單頁面數據請求接口壓縮到 1—2 個,過多的網絡接口請求,一是會有過多建鏈和斷鏈的網絡耗時,二是會提升接口請求失敗率。尤爲是相互依賴的接口,能夠考慮將請求進行合併。

請求提早

數據請求提早。首屏的數據若是在打開 webview 的瞬間已經準備完畢,那基本很快能夠將頁面展現出來。所以在對首屏性能要求較高的場景下,能夠考慮將接口請求提早在頁面打開前,如 APP 打開後就提早開始緩存用戶可能要打開的頁面數據,在用戶打開頁面時從本地緩存獲取數據。在實際項目中請求提早涉及兩個現實的問題,請求具體時機以及緩存問題。

  • 請求時機。我參與的項目中,用戶可能要打開的頁面不少,沒法提早預知要緩存哪一個頁面的數據,初期使用粗暴的方法是在 APP 首頁列表打開時把全部頁面數據所有提早緩存,列表數據太多時性能不好,最終優化方案是使用部分緩存的方式,只對列表可見項進行提早緩存,用戶在滑動頁面時,只緩存可見項的頁面數據,性能有明顯提高。
  • 緩存問題,客戶端提早緩存頁面數據,會遇到緩存一致性問題,如何更新緩存在體驗和正確性之間須要作權衡。我參與的項目沒有健全的推送機制,服務端沒法主動通知緩存更新,在這種狀況下,什麼時候更新客戶端緩存是一個難題,通常客戶端不會選擇短期輪詢方式進行緩存更新,由於輪詢會大量消耗手機電量,也會形成服務端壓力。最後使用一個折中方式,犧牲極少機率的正確性換取更好的體驗,客戶端會根據用戶的一些行爲來更新緩存,如殺進程、下拉刷新等,同時給緩存設定一個固定的有效期,有效期根據 APP 單次使用平均時長(如 15 分鐘)來設定,保證下次打開 APP 絕大多數用戶緩存能更新。

webview 初始化

webview 是移動端瀏覽器實例,幾乎具有 PC 端瀏覽器的絕大多數能力,客戶端在使用 webview 打開 H5 頁面前,須要實例化 webview 對象,其初始化的過程在 android 系統中須要大約 500ms 以上的時間。有一種手段是使用對象複用機制,提早建立 webview 對象池,須要使用 webview 時直接從池中獲取初始化完畢的對象,這種相似於線程池的方式能夠避免每次打開 H5 頁面都要初始化 webview 實例,從而提高頁面打開速度。

其餘

還有另一個徹底不一樣思路來優化移動端 H5 頁面打開速度,那就是服務端渲染,也稱之爲 ***,簡單來說就是服務端將頁面的 html 和數據提早組裝好再傳遞給瀏覽器,瀏覽器只負責解析 html 和展現,所以首屏渲染較快。可是會給服務端增長壓力和複雜度,現實中須要綜合考慮利弊以及 ROI 來選擇是否使用 *** 方案。

實踐效果

本人蔘與的項目在 H5 頁面只針對靜態資源和數據請求進行了優化,完成後得到效果仍是較爲理想的,見下圖綠色線是優化以後頁面打開的平均白屏時間,藍色是優化前的平均白屏時間,能看到優化成效仍是至關可觀的,若是能將 webview 的初始化時間也優化掉,基本上能達到頁面秒開。 watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

總結

以上是結合本身項目以及以往的經驗總結的較爲常規的針對移動端體驗優化的思路,比較淺顯,其實每個優化思路雖說起來簡單,可是在實踐中會由於各類因素(如投入產出比,先後端資源協調等)致使夭折,並且優化思路也須要分場景,須要因地制宜選用不一樣的方案。每個優化思路均可以寫長文進行深刻探討,體驗優化是一個馬拉松,須要長期持續的投入,有興趣的歡迎一塊兒交流 


 

關注我,獲資源乾貨watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=????關注 程序員乾貨分享

相關文章
相關標籤/搜索