天天看點

Weex實戰分享|企鵝電競Weex實踐和性能優化

Weex實戰分享|企鵝電競Weex實踐和性能優化

渠宏偉 企鵝電競前端團隊Leader

H5頁面存在的問題

H5頁面對比終端的不足,第一,加載慢;第二,互動差。

Weex實戰分享|企鵝電競Weex實踐和性能優化

加載耗時比較長,因為它受限于Webview,Webview在Android上啟動就比較慢,另外頁面資源加載慢。我們很多業務頁面都是用H5做的,長清單滾動和側滑操作存在明顯的卡頓,經過持續優化也很難和原生界面媲美。

H5極速加載方案 ——VasSonic

加載慢的問題,我們實作了H5極速加載方案 —— VasSonic,加載速度實作秒開,在手機QQ上廣泛應用。

WebView和頁面并行加載

資源離線預推

頁面局部重新整理

動态緩存

Weex實戰分享|企鵝電競Weex實踐和性能優化

H5頁面首屏實作秒開 (https://github.com/Tencent/VasSonic)

Weex實踐和收益

為什麼選擇Weex

企鵝電競正在快速發展中,我們需要一套兼顧性能與動态性的技術方案來支撐企鵝電競産品日益豐滿的業務需求,weex是一個不錯的選擇。

weex選擇了vue作為上層架構,代碼編寫體驗和使用vue差不多。企鵝電競前端團隊的許多項目之前也選擇了vue作為開發架構,小夥伴們可以快速上手。

facebook的專利許可證風波讓開發者們人心慌慌,不敢再使用他家的React Native。 weex借鑒了React Native的思想,是一種不錯的RN替代方案。

Weex實戰分享|企鵝電競Weex實踐和性能優化

我們選擇了Weex作為原生渲染方案,它的主要特點:

前端頁面原生渲染,增強前端頁面體驗

一次開發支援三端(Android、iOS、H5)運作,提高開發效率

在企鵝電競業務當中大量使用了Weex,如果想體驗一下可以下載下傳我們的APP,可能你都看不出來哪部分是原生做的,哪部分是Weex做的,它是一個融合的方案。

Weex實戰分享|企鵝電競Weex實踐和性能優化

獲得收益

Weex實戰分享|企鵝電競Weex實踐和性能優化

記憶體降低 45%,幀率提高 15.7%;打開耗時下降 44.9%

開發效率比終端提升 40%,有效釋放終端開發人力

頁面更新不依賴版本釋出,特性釋出效率提升

我們接入時首先做了一個建構流程的改造。這是Weex官方建構圖,用一個公共APP進行webpack打包。我們的應用比較複雜,往往在H5上有一些特殊的邏輯,或者在原生上有一些特殊的邏輯,如果是統一寫在app.js裡,就會造成兩邊打出的js有備援。

Weex實戰分享|企鵝電競Weex實踐和性能優化

我們就做了一下改造,其實改了頁面的開發方式。除了app.js之外,又分成兩個入口,一個是對web的,一個是對Weex的。

Weex實戰分享|企鵝電競Weex實踐和性能優化

分入口再引用相同的app.js,可以讓web版本和weex版本保持相同邏輯,也可以獨立擴充,互不影響。

頭部的{"framework":"Vue"}告訴解析器用Vue的文法解析JSBundle。如果删除了這行注釋,将會白屏。

Weex實戰分享|企鵝電競Weex實踐和性能優化

Uglify壓縮會删除注釋,導緻”接頭暗号”被删除。壓縮必須放在插入framework之前

Weex實戰分享|企鵝電競Weex實踐和性能優化

調用終端接口

我們的APP接入Weex之前是很成熟的APP,有大量jsapi,如果全部改造成module工作量太大,做法是統一做一個module轉發,直接傳過來,由module統一解析轉發到對應的邏輯,底層jsapi的解析和邏輯保持不變。這樣的話,我們的Weex頁面直接就內建了原來所有Webview的jsapi能力,是一個通用的。并且以後開發新的接口時,隻需要開發一份。

Weex實戰分享|企鵝電競Weex實踐和性能優化

H5中我們使用document.cookie可以擷取浏覽器的cookie資訊。

在weex中如何實作?我們利用weex提供的擴充module的能力,在終端中擴充一個擷取cookie的方法。

Weex實戰分享|企鵝電競Weex實踐和性能優化

接口請求支援cookie

iOS基于UI     webview共享cookie。iOS天然支援請求帶上cookie

android需要終端支援,使用cookieManager管理cookie資訊,攔截請求自動添加上cookie

Weex實戰分享|企鵝電競Weex實踐和性能優化

H5頁面經常使用UA判斷APP環境和版本号,為了相容H5的邏輯,我們在Weex中支援了userAgent,在weex.config.env添加userAgent屬性。 需要注意的是,從weex執行個體中擷取的userAgent是靜态的。一旦weex執行個體建立就固定下來,終端修改UA也不會跟着變化.

Weex實戰分享|企鵝電競Weex實踐和性能優化

如何實作1px

weex px問題是一個坑,定義成了自動縮放機關,颠覆了前端對px的了解。我個人認為,微信小程式的方案是對的,定義一個新的機關rpx實作自動縮放,不影響原來px的實作。

在我們的業務場景中需要使用weex實作titlebar。在寬屏手機titlebar會被縮放,跟終端的titlebar體驗不一緻。通過動态計算對應的px,重新設定樣式,實作和終端一緻的體驗。

Weex實戰分享|企鵝電競Weex實踐和性能優化
Weex實戰分享|企鵝電競Weex實踐和性能優化

橫屏适配

Weex實戰分享|企鵝電競Weex實踐和性能優化

裝置寬度deviceWidth是固定的,橫屏狀态下裝置寬度為手機長度,并不是我們的view寬度。看上面的公式,我們可以前端修改viewport寬度750。

Weex實戰分享|企鵝電競Weex實踐和性能優化

适配後就如下圖所示效果。注意,meta.setViewport執行時機比較晚,如果希望一開始得到準确的渲染寬度,需要終端同學幫忙weex初始化時設定viewport。

Weex實戰分享|企鵝電競Weex實踐和性能優化

項目比較常見的點選态多半是透明度的變化,如按鈕、清單、連結等,css的做法是添加僞類 (:active),weex中也同樣支援,但是weex需要在原樣式中添加 opacity:1,否則點選後回不到初始狀态;

Weex實戰分享|企鵝電競Weex實踐和性能優化

此外,:active使用時,background-image在ios下會失效。

文本從限制1行到不限制可以用lines:0

Weex實戰分享|企鵝電競Weex實踐和性能優化

圓角抖動問題

圓角按鈕會先顯示直角再變成圓角,出現明顯的抖動,問題存在于android下 weex sdk

Weex實戰分享|企鵝電競Weex實踐和性能優化

發現weex sdk代碼中做了64ms延時造成的,配合在新版本weex sdk解決了這個問題

Weex實戰分享|企鵝電競Weex實踐和性能優化

Android

OOM

PaintDrawable在API 21下偶現渲染crash

Bitmap回收後繼續使用導緻crash

instance被銷毀後調用Toast的NPE問題

WXThread.secure反射調用異常

iOS

未顯示禁用estimatedRowHeight導緻

tableview在更新資料源時偶現crash

布局時node->get_child傳回空指針導緻crash

text component渲染和測量高度時偶現crash

Android接入Weex crash率 0.13% -> 1.01%,我們遇到的這些crash問題在企鵝電競已經解決。

weex sdk生成的終端view中的id是自動生成的,自動化測試系統無法識别。

我們借助無障礙化ariaLabel屬性作為原生view自動化測試标簽。

Weex實戰分享|企鵝電競Weex實踐和性能優化

性能優化

1、使用storage緩存接口請求資料

2、優先使用本地緩存資料,同步請求更新緩存資料和頁面

Weex實戰分享|企鵝電競Weex實踐和性能優化

jsbundle預緩存優化

1、在現有的 weex 頁面配置檔案的基礎上增加一個字段 preload,當此字段值為1時候,對jsbundle檔案進行預緩存。

Weex實戰分享|企鵝電競Weex實踐和性能優化

2、提供js api : biz/preload 提供給前端進行對下一個頁面的預加載。biz/clearProload 用于前端對于既有緩存内容的清空.

3、對于緩存内容,使用LRU的算法進行管理,控制緩存總大小為20M。

4、對于使用緩存的内容,終端在ua上添加一個字段 PRELOAD/1 ; 1表示是預緩存内容, 0表示不是。

Weex實戰分享|企鵝電競Weex實踐和性能優化

我們一直關注頁面加載的性能,問題到底出在哪兒,是終端耗時,網絡耗時,還是頁面邏輯耗時,我們在Weex頁面上打了一系列點,Webview時期也打了很多點統計這些資料。終端、前端兩份上報,目的是互相對賬。

攔截請求開始、請求完成、RenderFinish計算網絡耗時(請求結束 - 請求開始)、終端渲染耗時(RenderFinish - 請求結束)

終端通過js api提供前端建立instnace時間點

終端、前端兩份上報,互相校驗資料,生成性能報表,快速定位性能問題産生的階段

Weex實戰分享|企鵝電競Weex實踐和性能優化

1、Android 更新weex 0.16版本module接口調用耗時大幅減少。

終端接口耗時優化,這是一個比較現實的問題。最早接Weex時接的是0.12版本,當時調用一次module接口50-60毫秒,後來更新0.16,這個問題就解決了,Weex團隊持續做優化,這是一件好事情。

Weex實戰分享|企鵝電競Weex實踐和性能優化

2、減少啟動頁面時并發調用module接口。

現在接口單次調用2-3ms,但是并發請求性能很低,需要60ms以上,這個對前端頁面是很大的損傷,希望這一塊能夠持續優化解決這個問題。

3、Android 調用時多次反射擷取類名導緻Dom渲染耗時過長。

Weex裡的小bug,調用時多次反射擷取類名,導緻Dom渲染耗時過長。其實一次調用時間并不長1ms,需要調一百多次,就造成很大的耗時了。

Weex實戰分享|企鵝電競Weex實踐和性能優化

Android Bitmap 記憶體優化

Weex實戰分享|企鵝電競Weex實踐和性能優化

使用Fresco管線加載圖檔,加載後不持有圖檔引用。

問題:

會将使用者目前不展示的圖檔也加載到記憶體中,實際占用記憶體變多,OOM問題嚴重。

引用不被持有會導緻Bitmap被回收後仍然被使用(3.2 - 3.4版本top crash—SIGSEGV (SEGV_MAPERR))

優化: 仿照Fresco的DraweeController管理WXImageView的bitmap引用。 顯示時加載,隐藏時解除引用等待回收。

OOM問題明顯緩解,bitmap被回收的crash問題也得到解決。

Weex實戰分享|企鵝電競Weex實踐和性能優化

GPU過度繪制是終端開發很關注的問題,通過優化層級,提升渲染性能。我們上了Weex後沒關注這個問題,重構按照以前的開發方式,設定很多層和背景色,生成的Weex頁面打開Android調試發現大面積是紅的,過度繪制很嚴重。

優化方法:

盡量不要設定背景色

不要過度嵌套,結構盡量扁平化

Weex實戰分享|企鵝電競Weex實踐和性能優化

Weex實踐分享——内部影響力

Weex實戰分享|企鵝電競Weex實踐和性能優化

希望優化的問題

橫豎屏切換方案支援

支援armabi-v7a的so包

元件統一開源:例如 jscore核心、debugger、gcanvas

更好的性能細分統計

高效的終端和Weex共享動态資料方案

更好的容錯: iOS JS call Native時,參數傳錯會造成終端crash

原文釋出時間為:2018-01-31

本文作者:渠宏偉