好奇移动端、桌面端是怎么实现列表控件渲染大量元素不卡顿的?

2024-07-22 23:17:07 +08:00
 rcocco
网页端是有多少 DOM 元素就渲染多少元素,不管这些元素是不是用户当前视口可见的,所以元素一多就会很卡。每次都要专门把渲染的逻辑写成虚拟滚动来解决这个问题,但用过的一些虚拟滚动库总是有各种各样的限制或小毛病,例如要求元素等高,滚动到底部不对劲等等。

我就很好奇其他端,像移动端和桌面端都是怎么解决这个问题的?搜索 [安卓 虚拟滚动] 还搜不到什么东西
4702 次点击
所在节点    程序员
40 条回复
codehz
2024-07-23 10:21:34 +08:00
(其实浏览器也不会绘制超过屏幕的内容( edge 有几个版本你就会在滚动过快的时候看到白屏被一个个方块填上的过程),但超过屏幕的内容不止是绘制的问题,还有布局等其他因素需要计算,加上为了 js 访问方便而设计的对象接口的 overhead 才会显得不能装太多东西,实际上就单纯说显示一个巨大的表格来说浏览器问题不是很大,好多设计起来就只有单页的文档(例如隔壁的 rust 的某文档,html5 的单页 spec ),其内容长度远超一般“无限滚动”正常用户能滚动到的范围,也可以顺利的在浏览器上呈现。。。(当然和一般无限滚动场景不同的是,它内容上是较为简单的,计算布局的压力也会小很多)
桌面端除了用虚拟滚动的思路之外,还有一种叫 imgui 的思路,其抛弃了控件的抽象,根据滚动位置直接计算出需要展示的范围,然后每次都只画用到的部分,也可以解决这个问题==(有一些商业表格控件就是这个思路)
之所以虚拟滚动一类的机制需要使用“复用”,其本质不是绘制元素有多慢,而是为了表达这个 UI 对象抽象带来的额外成本很高,不能简单的丢弃再重建,或者干脆建立一大堆放着
ZGame
2024-07-23 13:56:14 +08:00
上面的都说了虚拟滚动,其实网页端还有种做法就是自己用画布做渲染。
shadowyue
2024-07-23 14:02:11 +08:00
关于你说的,移动端有多少 DOM 就渲染多少 DOM ,这个是测试出来的结果吗?
这个问题应该是和样式有关,移动端的元素通过样式来定位有不少方式。
导致很多情况,不全部渲染出来就无法确定一个 dom 的真实位置。
但是据我所知浏览器也是尝试做了优化的,比如你包含很多 video 或者 canvas 元素的话,
一般情况下,不在可视范围是不会去渲染的。
lshbosheth
2024-07-23 14:02:32 +08:00
b821025551b
2024-07-23 14:04:28 +08:00
不卡么?去 12306 上搜一下惠州到东莞的车票试试
rb6221
2024-07-23 14:32:17 +08:00
你可以理解为虚拟滚动,但是他和 web 端的区别是:第一,他是官方维护的,第二,他的语言和框架就决定了性能够好。
stew5566
2024-07-23 14:33:36 +08:00
@ZGame 很多时候网页会需要交互吧,感觉画布添加交互是不是会麻烦些
ZGame
2024-07-23 14:47:44 +08:00
@stew5566 那肯定阿...
icloudguizhou
2024-07-23 14:48:20 +08:00
@b821025551b 最流畅的还是 M3Max 芯片 128GB RAM 的 mac 上安装拼多多 APP 买高铁票,一键免密支付还可以调用 touchID ,fantastic and smooth experiences than ever before,
icloudguizhou
2024-07-23 14:52:13 +08:00
现在 web 和 APP 客户端的边界已经模糊了。Mac 也支持 APP 了。 自动获取 Mac GPS 定位,调用 touch ID 验证支付密码,web url universal link 直接调到 APP 的 landing page, 原生运行比 iPhone mirroring 流畅
LavaC
2024-07-23 15:05:32 +08:00
不定高的元素本来就没法实现完全准确的虚拟滚动,不渲染不知道高度->不知道高度就没法给你正确的 padding
qrobot
2024-07-23 15:07:49 +08:00
@LavaC 不固定高的元素可以实现虚拟滚动啊, 因为元素最终渲染到页面一定是有高度的, 只不过自己需要计算出来高度而已
qrobot
2024-07-23 15:09:18 +08:00
@LavaC 我自己实现的虚拟滚动, 在快速滚动下不闪动, 并且性能很强, 我试过 10w 列 * 10w 行, 这个时候才开始卡顿, 而且这个时候的卡顿还有优化空间
Anarchy
2024-07-23 15:21:03 +08:00
感觉搜不到 Android 虚拟滚动是这部分属于默认实现了,导致根本不理解什么是虚拟滚动。我刚开始学其他平台都好奇怎么没有 ListView 的组件只有个 scroll view ,都不怕卡的么。
rcocco
2024-07-23 18:01:04 +08:00
学到了,原来各端其实都得做虚拟化列表,有的是开发者自己做,有的是原生控件内部在做。

感谢大佬们
furlxy
2024-07-23 19:09:48 +08:00
iOS UITableView 享元模式
jones2000
2024-07-23 22:38:13 +08:00
虚拟表格+画布自己绘制表格,10W-100w 条数据显示完全不卡。
Chuckle
2024-07-24 11:10:08 +08:00
@LavaC 写过个不定高的虚拟瀑布流 demo ,准确的布局还是做得到的,https://list.qcqx.cn/#/list/virtualwaterfall
HangoX
2024-07-24 17:36:20 +08:00
只有 web 端才有虚拟滚动的概念,其他平台都是原生滚动。虚拟滚动是相对于浏览器的滚动条而说。原生开发本来就是那个滚动条。只是原生开发都考虑会回收利用问题
LavaC
2024-07-24 22:35:09 +08:00
@Chuckle 我固有印象了,该进行一个代码的学习

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1059281

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX