虚拟滚动技术 --- 解决加载大量列表DOM导致页面卡顿

网页dom元素过多为什么会导致页面卡顿

1、dom过多,占用过多的内存。
2、操纵dom时触发重排重绘,消耗浏览器性能。特别是每一次滚动事件将会让对应 DOM 中的所有元素重新渲染。
3、资源加载阻塞,比如js资源放在body之前、行内script阻塞、css加载会阻塞DOM树渲染(css并不会阻塞DOM树的解析)资源过大阻塞

至于第二个问题,详见网红问题--前端性能优化(全流程) 或者 js回流和重绘

现在看来,这两点大条件是客观存在的,我们无法改变,所以这时候解决的方案就呼之欲出了,别让浏览器一次性渲染这么多元素,这里通常会对应三种做法来减少元素渲染。

数据分页

这个方案是大家浏览到页面所常用的,通常在需要展示非常多行的数据时页面会采用分页的做法来分割数据,但在SQL结果集的场景下并不是通用方案,原因是虽然该方法减少了一次性所渲染的行数,但是如果查询的表列数非常多的话,还是有很大概率需要渲染非常多的元素,所以不是一个稳妥的选型。

无限滚动

该方案的解决方法是第一次只渲染所能承受范围内的数据量,当滚动条拖动接近底部(或右部)时,再去追加下一批所需要渲染的元素,该方案也是有一个明显的缺陷在于,无限地滚动下去必然会触及浏览器的性能瓶颈,而且所需要渲染的元素会越来越多,性能迟早会被拖垮。

虚拟滚动

其实答案已经隐藏在上面两种解决方案里面了,数据分页的方案是一次性渲染固定行数和列数的数据量,缺点是怕一次性的量就逼近上限。无限滚动的方案是想看更多数据的时候再继续渲染,不看就不渲染避免性能浪费,但缺点就在于只要一直触发“继续看”的操作,那么之前遗留的数据将会越来越多导致性能雪崩。

这时候可以把两个方案中和一下,既然在有限的视窗中我们只能看到一部分的数据,那么我们就通过计算可视范围内的单元格,这样就保证了每一次拖动,我们渲染的 DOM 元素始终是可控的,不会像数据分页方案怕一次性渲染过多,也不会发生无限滚动方案中的老数据堆积现象。接下来我们用一张图来表示虚拟滚动的表现形式。

虚拟滚动原理

根据图中我们可以看到,无论我们如何滚动,我们可视区域的大小其实是不变的,那么要做到性能最大化就需要尽量少地渲染 DOM 元素,而这个最小值也就是可视范围内需要展示的内容,也就是图中的绿色区块,在可视区域之外的元素均可以不做渲染。

可以通过如下几步来实现虚拟滚动:

  • 每一行的高度需要相同,方便计算
  • 需要得知渲染的数据量(数组长度),可基于总量和每个元素的高度计算出容器整体的所需高度,这样就可以伪造一个真实的滚动条
  • 获取可视区域的高度
  • 在滚动事件触发后,滚动条的距顶距离也可以理解为这个数据量中的偏移量,再根据可视区域本身的高度,算出本次偏移的截止量,这样就得到了需要渲染的具体数据
  • 如果类似于渲染一个宽表,单行可横向拆分为多列,那么在X轴上同理实现一次,就可以横向的虚拟滚动
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 导读 本文适用于以下三种读者 只想要了解一下虚拟列表可阅读“实现一个简单的虚拟列表”之前的部分 想初步探究虚拟列表...
    gjt19970425阅读 22,011评论 0 17
  • 前言 场景是小程序长列表优化,框架基于mpvue,固定高度。(动态高度暂时先不考虑) 关于recycle-view...
    依然还是或者其他阅读 1,234评论 0 0
  • 0 前言 项目中某个页面因业务要求会有很多图片,加载速度不给力,用户体验很差。在处理这个问题的过程中,在网上参考了...
    0o刀刀o0阅读 2,166评论 0 2
  • 为什么使用虚拟滚动 相信在前端业务中不乏需要渲染长列表的场景,当渲染上千或者上万条数据时,DOM操作是很昂贵的,一...
    Vv_Jiang阅读 2,413评论 0 6
  • 当我们遇到需要一次性向页面插入十万条数据的情况下,该如何保证页面不卡顿,维持一定的页面渲染性能 😲 场景:插入十万...
    Adder阅读 1,508评论 1 5