【问题标题】:Does ListView automatically support lazyload?ListView 是否自动支持延迟加载?
【发布时间】:2016-08-26 07:06:40
【问题描述】:

我在列表视图中有图像,当我向下滚动时。似乎它可以即时渲染图像。是懒加载吗?如果是,那么为什么存在延迟加载库。

看看情况。

我在列表视图中呈现 25 张图像。第一次加载所有图像大约需要 5 分钟。渲染所有图像大约需要不到 10 秒的时间?如果 listview 做延迟加载,那么为什么加载所有图像需要大约 5 分钟?

【问题讨论】:

  • 有什么理由否决我的问题?
  • 有人应该在投反对票之前写评论。所以其他人可以知道你为什么不喜欢这个问题。奇怪的人
  • 赞成你的问题,因为它是真实的并且写得很清楚。

标签: android listview reactjs mobile react-native


【解决方案1】:

React 本机 ListView 确实实现了一种延迟加载,但仅限于基于 pageSize 属性和您的 Scroll 位置呈现行本身。假设你有 100 行,ListView 不会在给定时间呈现所有行。当用户向下滚动时,它将仅呈现特定数量的行并呈现更多行。延迟加载模块通过在接近视口之前不渲染实际的行视图来进一步增强这一点

其次,React Native 在设备上缓存图像。因此,每当加载远程图像时,它都会根据图像的 url 检查本地缓存。它存在一个缓存,它使用该图像而不是发出新的网络请求。

【讨论】:

    【解决方案2】:

    while1 已回答您的问题。但我想补充一点。这在很大程度上取决于您所说的延迟加载是什么意思。

    1. 您的意思是在用户向下滚动时从 API 获取数据吗?
    2. 或者您的意思是在用户向下滚动时呈现预取数据?

    如果你的答案是 1,那么没有。 ListView 与 API 调用无关。它必须由您编写。如果你的答案是 2,那么我找到了一个 awesome source 的关于 ListView 的信息。如果链接断开,我仍然会在此处发布相同的答案。

    简而言之,ListView 隐式处理了许多渲染复杂性。

    负载平衡

    在 UITableView 中,当一个元素出现在屏幕上时,你必须 同步渲染它。这意味着你有不到 16 毫秒的时间 做。如果你不这样做,那么你会丢弃一帧或多帧。如果你是 渲染新闻提要故事等复杂元素,基本上是 不可能满足这个时间表,所以你注定要丢帧。

    使用 ListView,当您到达当前屏幕的末尾时,您可以 提前准备更多要渲染的行。这些行将是 在不同的线程中呈现,因此不会冻结 UI 线程 加工。它工作的原因是负载不 均匀分布。你不需要在每一个单曲上呈现一个新故事 框架,大多数框架只是滚动,不需要新故事 出现。

    ListView 也会一次渲染一个元素,所以如果你是 在渲染更多行时与某些元素交互,它不会 阻塞,直到所有行都被预渲染,它只会阻塞 一行。

    内存管理

    UITableView 在内存方面非常保守,它积极地重用 细胞。这个决定是在 iPhone 1 中做出的 极其稀缺。问题在于重用单元格是 开发人员极易出错。给你一个脏东西, 你不知道发生了什么突变,你需要 重新配置它看起来像你想要的。在我们的 iOS 应用程序中,这导致 错误太多了。

    重用cell的问题是有些cell有内部状态 (视频播放器运行、文本输入、水平滚动位置...)当 您重用它们,您需要能够序列化该状态并将其放入 背部。这并不总是可能的,也不容易,所以你通常要么 松开此状态,否则它会在新行上传播并导致错误。

    我们在 React Native 上发现它在 iPhone 上足够快 4s 为每一行创建新的单元格。所以,我们不需要 把这个非常严格的约束强加给我们自己。在您的屏幕截图中,您 注意到您滚动一段时间后我们不会删除行。 这不完全正确,我们不删除虚拟 dom React 方面的表示(你在 chrome 开发中看到的) 工具),但我们确实从“dom”中删除了这些元素并保留它们 参考。

    当它们再次可见时,我们将它们放回 dom。万一我们 内存不足或列表太大,我们可能会销毁这些和 从头开始重新创建它们(失去上面提到的状态) 未来。我们还没有做这个性能优化,但是 用户代码不会受到影响。

    我们试图积极地删除 iOS 视图,但我们发现 这样做实际上非常昂贵。最好离开他们 挂起而不是删除它们。

    变化检测

    在 ListView 中,我们有一个支持不变性的 DataSource 对象。如果 你有一个包含 1000 个元素的列表来渲染,你想让那些 1000 个元素不可变,这意味着您可以检查前一个 === 下一个并立即知道是否发生了变化。这样,当任何事情发生变化时,您唯一要做的就是遍历 这两个列表并进行那些非常快速的平等检查并知道什么 行改变了。然后只更新那些。

    布局

    在 UITableView 中,你必须指定每一行的布局 即使它们没有显示在屏幕上。所以,在某些情况下 它不是固定大小,您必须基本上将元素渲染为 知道它的大小,并预先支付高昂的成本。这也很 手动操作很烦人。

    在 ListView 中,由于 React Native 拥有布局系统,你不需要 自己做所有艰苦的手动计算。当一行是 渲染,它会更新大小。唯一的缺点是 滚动条有点时髦,但我相信我们能上来 用启发式方法在未来平滑它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      相关资源
      最近更新 更多