我在listview中有图像,当我向下滚动时。它似乎在飞行中呈现图像。是懒惰吗?如果是,则为什么存在lazyload库。
查看secnario。
我在listview中渲染了25张图片。在第一次加载所有图像大约需要5分钟。在需要不到10秒的时间渲染所有图像之后呢?如果listview做了lazyload那么为什么加载所有图像需要大约5分钟呢?
答案 0 :(得分:2)
React native ListView实现了一种Lazy加载,但仅限于基于pageSize属性和Scroll位置呈现行本身。假设您是100行,ListView不会在给定时间呈现所有行。当用户向下滚动时,它将仅呈现特定数量的行并呈现更多行。延迟加载模块通过不渲染实际的行视图,直到它靠近View端口
,进一步增强了这一点其次,React Native在设备上缓存图像。因此,无论何时加载远程图像,它都会根据图像的URL检查本地缓存。它存在缓存,它使用该图像而不是发出新的网络请求。
答案 1 :(得分:2)
while1已回答了你的问题。但我想补充一点。它在很大程度上取决于懒惰负载的含义。
如果你的答案是1,那么没有。 ListView
与API调用无关。它必须由你写。如果您的答案是2,那么我找到了ListView
有关ListView
的信息。我仍然在这里发布相同的答案,以防链接中断。
简而言之,{{1}}隐含地处理了许多渲染复杂性。
负载平衡
在UITableView中,当一个元素出现在屏幕上时,你必须这样做 同步渲染它。这意味着你的时间不到16毫秒 做到这一点。如果你没有,那么你丢弃一个或多个帧。如果你是 渲染复杂的元素,如新闻源故事,它基本上是 不可能满足这个时间表,所以你注定要丢帧。
使用ListView,当您到达当前屏幕的末尾时,您可以 提前准备要渲染的更多行。那些行将是 在不同的线程中呈现,因此不会冻结UI线程 处理。它工作的原因是负载不是 均匀地传播。你不需要在每一个上面渲染一个新故事 框架,大多数框架只是滚动而不需要新故事 出现。
ListView也会一次呈现一个元素,所以如果你是 在渲染更多行的同时与某些元素交互,它不会被激活 阻止直到所有行都已预先渲染,它只会阻止 一排。
内存管理
UITableView在记忆方面非常保守,它积极地重复使用 细胞。这个决定是在内存所在的iPhone 1中做出的 非常稀缺。这个问题是重用单元格 对开发人员来说非常容易出错。给你一个脏物, 你不知道发生了什么突变,你需要 重新配置它看起来像你想要的。在我们的iOS应用中,这造成了 SOOO很多错误。
重复使用细胞的问题是某些细胞具有内部状态 (视频播放器运行,文本输入,水平滚动位置......)何时 你重用它们,你需要能够序列化该状态并将其放置 背部。这并不总是可行也不容易,所以你通常也是 松散此状态或它在新行上传播并导致错误。
我们在React Native上发现的是它在iphone上足够快 4s为每一行创建新单元格。所以,我们并不需要 对自己施加这种非常严格的约束。在你的截图中,你 注意到滚动一段时间后我们不会删除行。 这不完全正确,我们不会删除虚拟dom 在React方面的表示(你在chrome dev中看到的) 工具),但我们确实从" dom"中删除了这些元素。并保持他们的 参考
当它们再次可见时,我们将它们放回到dom上。万一我们 内存不足或列表太大,我们可能会破坏那些和 从头开始重新创建它们(失去上面提到的状态) 未来。我们尚未完成此性能优化,但是 用户代码不会受到影响。
我们试图积极删除iOS视图,但我们发现了这一点 这样做实际上非常昂贵。离开他们会更好 悬挂比移除它们。
更改检测
在ListView中,我们有一个有利于不变性的DataSource对象。如果 你有一个要渲染的1000个元素的列表,你想要制作它们 1000个元素不可变,这意味着您可以检查前一个元素 ===下一个,立即知道是否有变化。这样,当任何改变时,你唯一要做的就是遍历 这两个列表,并进行那些非常快速的平等检查,并知道什么 行已更改。然后只更新那些。
<强>布局强>
在UITableView中,您必须指定每一行的布局 即使他们没有在屏幕上显示。所以,在哪些情况下 它不是一个固定的大小,你必须基本上渲染元素 知道它的大小,并预先付出高昂的成本。它也非常 很烦人这样做。
在ListView中,由于React Native拥有布局系统,因此您并不需要 自己做所有那些辛苦的手工计算。当一行是 渲染后,它会更新大小。唯一的缺点是 滚动条有点时髦,但我确信我们能够出现 通过启发式方法在将来平滑它。