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页面,若是有便进行页面复用,经过数据刷新页面,同时经过调整堆栈将页面显示出来。

相关文章
相关标签/搜索