ListView性能问题
这个问题一直存在,官方也没有更好地解决办法,我曾经尝试过将未显示的row设置为空View,但是效果并不算很好。目前只有从oc角度去优化或许是最终的办法。
请问有解决方案了吗~
没有,目前测试了很多种,其实都不好,都存在内存过大风险
可以使用onEndReached来加载部分row,当用户下滑接近底部时再加载更多的内容。 具体可以参考UIExplorer的Camera Roll例子,不过这个例子有bug,具体可以见我提的issue https://github.com/facebook/react-native/issues/7237
你可能理解错了,我说的是当列表刷到10页以上时,如何解决listview内存复用问题,目前listview采用的是scrollView,在android上已经实现复用了,但是,ios scrollView是有多少item内存中就存在多少,你说的问题是,一个初始列表很多时,第一次init加载部门,然后到底部再加载,这是另一个问题,
我明白你的意思了,react-native的Listview确实就是在scrollView里面不断添加row,但row移出可见范围之外后依然还在scrollview里面,不像安卓和ios的在移出视野之外后可以继续被后面出来的row复用。
不过这个问题在高性能手机上不大,我昨天改写了Camera Roll的例子,把它改成无限加载照片,在我的iphone 6s上面加载速度非常快,而且还是在没有关闭dev的模式下,死循环加载了很久很久才崩溃退出,正常人是不会在一页浏览这么多内容的。
错了,listview性能不解决,rn难上大舞台,你可能没有测试过,基本的app都有无限列表的需求,而且,你用的6s啊,你去5上试试
@soliury
react-native的ListView在Android上也没有实现复用,虽然也可以进行脏数据检查,但也是重绘,其实现原理跟原生实现有巨大差别。
@narychen
无限加载不是解决办法,即使是原生实现,也不敢写成无限加载的。你觉得实际体验感觉没问题,最终可能无法通过性能测试。
ListView这个问题官方早晚都需要解决
帅哥,有qq群什么的吗?一直没在国内找到react-native的组织。。
@TakWolf , 是的,但是比ios上的listview好多了,而且view一直稳定在几个,隐藏的view都drop掉了,当然这样也有开销,但是,比listview一直存在要好多了
@soliury react-native问题很多的,远不止listview这么一个问题,navigator的切换单线程加载也是个很头疼的问题,如果加载目标很大,会很慢。还有很多很多问题,我在官方github上提的好几个issue到现在没人解答,所以我现在遇到问题都懒得去提问了。
@soliury 原生的ListView重用实现思路,有一个控件回收池,可以控件级别重用 React-native在Android上有自己的一套绘制逻辑,ListView的实现相当于动态创建删除 iOS上我没有详细的研究,但是感觉原理类似 实际测试,在Android部分设备上,Listview还是有明显的抖动问题的
个人觉得,目前ListView的API设计,无法实现重用,可能的一个接口设计感觉应该是这样的: ListView创建的时候,绑定一个Component的回收池,每一个item做成一个Component,动态回收
而不是像现在这样每次调用方法重绘
@narychen ,尽量少去rn github提问嘛,毕竟现在issue不是解决问题的嘛,而且这种问题,一般都有重复问题了,所以一般就没有人回答了,
@soliury 提的都是bug或者功能缺失,我从来不会去提怎么做这种问题。
@narychen suoga
今天用ListView做了浏览手机相册的功能,在我的一加手机(3G内存)上确实没能浏览完所有照片就崩溃退出了,而且是关了dev的优化模式下试的。
这个问题比较头疼
苹果6s没有崩溃可能是因为我的苹果手机上照片没有一加那么多。
还是等官方解决吗?
@codetomylaw 官方有removeClippedSubviews, 详见http://facebook.github.io/react-native/docs/performance.html
@narychen 然而并没什么用
@narychen 确认没什么用。
@codetomylaw of course 有用。我如果关闭这个功能安卓上面的cameraRoll很快就挂掉了。
没有卵用。又过了这么长时间,facebook仍然没有推出重用方案的ListView。 Component在设计上就存在缺陷。
http://www.open-open.com/lib/view/open1462951473401.html
@narychen cameraRoll很快就挂掉 和这个没关系,你也可以模拟器上看下内存对象情况。
官网解释如下: “当removeClippedSubviews这一选项设置为true的时候,超出屏幕的子视图(同时overflow值为hidden)会从它们原生的父视图中移除。这个属性可以在列表很长的时候提高滚动的性能。默认为false。(0.14版本后默认为true)” 这是一个应用在长列表上极其重要的优化。Android上,overflow值总是hidden的,所以你不必担心没有设置它。而在iOS上,你需要确保在行容器上设置了overflow: hidden。
facebook的效率真的很让人捉急,有一个相关的bug已经拖了半年了,也没有解决,而且这个bug很严重,不解决产品根本就没法让人用。 https://github.com/facebook/react-native/issues/1831
我读了 https://github.com/facebook/react-native/issues/499 这个issue的所有评论终于明白了为什么打开removeClippedSubviews对我的app效果很明显,因为这个评论里的解释 https://github.com/facebook/react-native/issues/499#issuecomment-156726735 我在显示照片库的listview里没有用thumbnail, 所以显示的都是原图,这样如果不开启removeClippedSubviews很快就会挂掉,但开启这个虽然不能回收view内存,但却能回收image,所以效果立竿见影。 但是Listview的问题依然在,我在一部有很多照片的手机上浏览很多照片后最后还是会因为内存问题闪退。
补充一点,这个issue的最后有个咱自己人写的可回收复用的Listview 他参照了wix的ios实现方案做了android的实现,我暂时还没时间去研究这个方案到底是不是凑效。 各位有空可以研究下。 链接分别是 https://github.com/droidwolf/react-native-RealRecyclerView http://blog.wix.engineering/2016/06/30/recycling-rows-for-high-performance-react-native-list-views/
@narychen 这篇文章我读过,也测试过它的性能,确实已经解决了android上内存问题。 但是它存在一个问题,就是如果想实现Listview的功能,类似renderHeader 、renderFooter、实现分页等功能,都得自己去完善。
renderHeader这些功能性问题都好办,关键是这种实现会不会有什么隐藏的陷阱。 https://github.com/facebook/react-native/issues/499#issuecomment-87821298 这个链接里VJ大神解释了他们为什么不选择UITableView的复用方式,这种原生的复用方式给他们带来了很多问题。如果只是简单的测试内存使用情况不一定能发现在真实产品中才会出现的问题。因为实际产品里每个row可能里面会包含很多东西,尺寸大小,以及资源引用,这些情况下可能会出现测试里一行就是一个简单的View不会出现的问题。