Weex-iOS 內存分析

簡書性能優化

前言

引入weex提升了業務開發的效率以及靈活度,可是在使用過程當中仍是存在很多問題,其中內存上就有很明顯的問題bash

1、weex頁面與原生頁面對比存在的內存問題

一、weex頁面內存開銷過大

如圖進行頁面切換:weex


在進行到weex頁面的時候內存暴漲。

二、頁面Push跳轉堆棧內存泄漏。

從首頁Push跳轉到weex頁面,加載數據,再返回,重複屢次得出下圖的結果:ide

而Push跳轉到原生頁面再返回,重複屢次得出下圖內存結果:工具

從上面兩張圖能夠看出:原生頁面返回後從堆棧移除後會進內存回收;而從weex頁面回到首頁,內存沒有徹底回收,存在必定的內存泄漏,重複屢次能夠看到內存相比較一開始會有明顯的增長。佈局

三、列表滑動的內存狀況

在沒有采用 標籤的狀況下: 性能

weex頁面列表滑動內存狀況如圖:

weex頁面滑動內存狀況
weex頁面滑動內存狀況

經過趨勢圖列表滑動過程當中內存一直持續暴漲,沒有進行復用減小內存開銷。

原生頁面列表滑動內存狀況如圖:

原生頁面滑動內存狀況
原生頁面滑動內存狀況

從圖中能夠看到,在滑動初始階段,內存增加比較快,以後的滑動過程當中對前面的控件進行復用,內存開銷減小,曲線變得平緩,沒有出現內存持續暴漲。

四、 weex頁面內存問題總結:

一、weex頁面滑動沒有采用複用機制,致使內存會跟着滑動持續暴漲
二、weex頁面佔用內存開銷太高,多個weex頁面可能致使APP由於內存過大而Crash。
三、weex頁面從堆棧移除內存沒有徹底回收,存在必定的內存泄漏。優化

2、內存問題緣由分析

一、滑動過程內存持續暴漲問題

weex官方文檔上,建議使用高性能可複用<cell><list>,而【搜索頁】、【樂瘋搶】等weex頁面業務代碼中直接採用了<div><scroller>實現列表的佈局,致使內存問題的出現。spa

這裏咱們經過Weex源碼,對四個標籤進行分析3d

能夠在WXSDKEngine 中能夠看出各個標籤對應的類:

<div> 對應WXComponent
<scroller>對應WXScrollerComponent
<cell>對應WXCellComponent
<list>對應WXListComponent複製代碼

<div>對應的WXComponent 至關於原生iOS控件的UIView,是全部視圖的基類,一個普通的視圖沒有性能優化、複用回收的機制。

<scroller>對應的WXScrollerComponent結構以下:


並沒有相關複用回收的屬性,主要是提供一個能夠滑動的容器。

查看<cell>對應WXCellComponent類的實現代碼能夠發現,WXCellComponent相比較WXComponent 擁有複用回收的相關屬性isRecycle

<list>對應的WXListComponent的結構如圖:


在成員列表中能夠看到使用了iOS原生的UITableView,而且實現了使用了UITableView的代理方法,實現了iOS的複用機制,如圖:

同時WXListComponent實現了WXCellComponent中的代理方法,WXCellComponentWXListComponent相關聯繫。

所以<list>基於iOS的UITableView複用機制,實現高性能了可複用的列表容器。
結合<cell>能夠實現一個高性能的列表展現頁面。

所以採用<list><cell>代替<scroller><div>解決滑動列表內存暴漲的問題。

二、weex頁面內存開銷太高的問題

經過Instrument工具進行內存分析,發如今進入weex 頁面時VM ImageIO_GIF_DataVM ImageIO兩個對象內存異常暴漲。

VM ImageIO_GIF_Data 內存增加狀況:

VM ImageIO 內存增加狀況:


VM ImageIO_GIF_Data 由7.92M增加到16.55M, VM ImageIO由0.11M增加到了1.02M,進入Weex頁面時,這兩個對象總共增長了9.54M,而整個Weex頁面初始狀態佔用內存爲15M左右(原生【商品詳情】頁:7M左右),佔據了整個Weex頁面內存的約60%。
而在原生頁面中, VM ImageIO_GIF_DataVM ImageIO對象幾乎沒有增加。
而這兩個對象與 CoreGraphics中進行圖片繪製、圖片渲染、圖片讀寫等相關方法有關,而CoreGraphics爲相對底層的模塊,相關方法比較消耗性能、內存,而且容易產生內存泄漏。
初步能夠斷定,weex中大量調用了 CoreGraphics中圖片處理的相關方法,致使了weex頁面內存開銷過大。

接着在WeexSDK的源碼中查找CoreGraphics相關方法,定位問題。
在查找過程發現,weex經過CoreGraphics繪圖方法將 等控件實例繪製成位圖進行顯示,以適應weex中的CSS佈局。
WXComponent+Display 中,能夠看到將控件繪製成圖片的代碼,並在 layer上顯示:

經過這部分的代碼能夠定位到weex頁面內存開銷過大的主要緣由是: weex SDK 調用了CoreGraphics方法將頁面中的 等控件繪製成圖片再佈局顯示,佔用了大量的內存。

weex的內存泄漏也與大量調用了CoreGraphics中方法有關。

經過Leaks工具定位到weex頁面內存泄漏對象爲CGDataProviderCreateWithCopyOfData



CGDataProviderCreateWithCopyOfData爲調用 CoreGraphics相關方法產生的對象。
weex SDK調用 CoreGraphics中的相關方法,可是沒有及時地釋放對象,致使了內存泄漏。

weex SDK 大量CoreGraphics方法將控件繪製成圖片再佈局顯示,佔用了大量的內存,同時也致使了資源回收不及時的問題。

解決方案:

一、限制堆棧中weex頁面個數:天貓採用的也是該方案,經過控制頁面級數,控制內存,防止由於堆棧過多的weex頁面,內存過大致使異常Crash。 二、頁面複用:在打開weex頁面前,判斷堆棧中是否有該weex頁面,若是有便進行頁面複用,經過數據刷新頁面,同時經過調整堆棧將頁面顯示出來。

相關文章
相關標籤/搜索