下一代的虚拟滚动介绍

319 阅读6分钟

在浏览器中渲染大型数据集,同时对性能和可访问性进行优化是一个复杂的问题。目前处理长数据列表的方法是使用无限滚动模式,在数据进入视图之前逐步加载和渲染数据。这种方法是有取有舍的,我们将详细介绍这种方法,以及即将推出的新功能和标准,这些都将在未来改善虚拟滚动。

虚拟滚动在整个网络中已经很普遍了。社交媒体、新闻聚合器和照片网站都使用虚拟滚动来展示帖子列表。地图供应商呈现出在两个维度上无休止地滚动的瓷砖。有数万行的大型数据集被显示在数据网格或电子表格中。

Process of Virtual Scrolling

虚拟滚动的挑战

创造一个好的虚拟滚动体验是关于平衡权衡的。由于渲染许多DOM节点所需的时间;加载数据、图像和其他资源所需的时间和带宽;以及为内容(可能永远不会被用户查看)分配的内存,前期渲染太多影响了性能。在一个理想的情况下,在不影响终端用户体验的情况下优化性能。

分页

早期解决这一难题的方法是采用更传统的分页模式,即向用户展示任意数量的项目,如10个或25个,只有当用户明确要求下一组数据时,才会呈现下一个数据块,通常是通过与用户界面交互,如点击下一页按钮。理想情况下,渲染大型或永不结束的数据集的性能得到优化,而不影响终端用户体验。

分页方法实现起来很简单,但对于大多数用例来说是次优的,因为它需要额外的用户交互,而且不能立即显示下一组数据,也不能主动获取这些数据以预测终端用户的需求。

页外预渲染

更现代的实现方式是使用无尽的滚动方式。该组件负责预取模型并在必要时获取额外的数据和资源。我们进行了优化,以确定在屏幕外渲染多少行数据,以及何时获取数据以提供坚实的用户体验。该组件不断地添加、删除、重复使用和渲染行,以防止应用程序的内存以无限制的方式增加。

聪明的无尽滚动的实现会添加某种调试机制,以防止在用户快速上下滚动时加载过多的数据,常见的模式是在等待15ms的不作为后再获取和渲染更多的数据。所有这些都需要大量的复杂性和协调。它甚至在移动设备上也能很好地工作,但需要注意的是,页面上实际存在的数据只有一小部分,因此像 "在页面中查找 "这样的功能并不能像预期那样工作。

交叉点观察者

几年前,人们开始努力提供标准原语来解决这些模式。

WICG最近引入了交叉观察者API,它可以确定一个元素是否在另一个元素里面或者在视口里面。交叉观察者基元大大减少了确定一个元素是否应该被显示的必要计算,它还提供了交叉状态变化时的本地通知。

(虚拟滚动器

在交叉点观察者的基础上,最近提出了一个内置的自定义元素。正如在虚拟滚动器自定义元素的动机中所解释的。

虚拟滚动器很复杂,而且很难做对。事实上,在虚拟化内容上获得一流的体验目前是不可能的,因为浏览器没有提供正确的钩子:像可访问的地标导航、在页面中查找或页面内的锚点导航都是完全基于DOM结构的,而虚拟化内容根据定义并不在DOM中。此外,今天的虚拟化内容不能与搜索引擎爬虫一起工作,这意味着那些关心搜索引擎排名的网站无法应用这一重要的性能技术。这对网络是不利的。

应该使虚拟滚动模式更强大,更简单地实现。建议还提供了关于如何最好地处理不同大小的数据集和较大数据集的建议。有了这些建议,我们仍然鼓励开发者为加载数据实现一个虚拟化机制。此外,虚拟滚动器建议并不是为了解决数据网格的使用情况。

交叉点观察者v2

交叉观察者API第二版的工作也已经开始,打算解决交叉观察者的一些边缘情况,包括一个元素是否被隐藏或被其他内容覆盖,或者是否由于风格上的修改而不可见,如变换、不透明度和过滤器等。

交叉观察者第二版API中的新增内容从性能影响来看被认为是比较昂贵的,目前的建议是开发者只在需要时选择加入第二版功能。

装载属性

虽然交叉观察者API很强大,但它并不能处理在用户滚动到用户界面的那一部分之前加载图片的用例。目前,许多基于交叉观察者API的实现都会检查一个元素是否在一个比视口大一些的盒子里相交,以支持这种情况。

对于这个用例,一个新的API致力于解决图像和iframe内容的这个挑战:加载属性。新的加载属性支持三个值。

  • lazy(根据需要进行懒惰加载)
  • eager(立即加载)
  • 自动(由浏览器为你决定)

懒惰属性应该在用户滚动到图片之前加载一点,以便最终的用户体验看起来是无缝加载图片。

总结

虽然不是所有的虚拟滚动的挑战都已经通过标准化得到了解决,但我们用大型数据集构建用户体验的基础正在显著改善。

如果你需要帮助创建和优化大数据集的用户体验,请与我们联系,讨论我们可以如何帮助你!