【js】我们需要无限滚动列表吗?
无限滚动列表,顾名思义,是能够无限滚动的列表(愿意是指那些能够不断缓冲加载新数据的列表的)。但是,我们真的需要这样一个列表吗?在PC端,浏览器的性能其实已经能够满足海量dom节点的渲染刷新(笔者经过简单的测试,1w+的节点并没有很明显的卡顿),但是同样的dom数量在移动端却不行,在dom结构合理的情况下,能够保持在2K+的dom数量已是一个很不错的列表了,但是dom数量再进一步增加就会明显影响页面的渲染效率,也正因为此原因,才有了此文关于无限列表的一些思考和探索。
首先,为什么会卡顿?因为dom数量的绝对值上的不断增多,在后续的交互上(如滚动,局部更新)都会导致页面渲染性能的下降。
那么,应该如何解决?既然是dom数量过多引起的,最简单也最有效的方法自然是减少dom数量。在jQuery时代,笔者便见过一种思路(其实本质实现至今也没有太大的变化):
1、只渲染特定几屏的数据,将多余的数据缓存在内存中,并不直接实例化到dom tree上,减少dom的绝对数量;
2、监听滚动事件,在滚动的时候动态的更新dom,让用户在视觉上看不出区别;
jQuery的实现由于年代久远,已经找不太到了,不过笔者在react社区找到了一个比较好的实现:react-virtualized,值得一提的是,它还将我们的滚动场景区分为了viewport内的局部滚动,和基于viewport的滚动,前者相当于在页面中开辟了一块独立的滚动区域,属于内部滚动(和iscroll的滚动很类似,顺带一提iscroll也给出了iscroll-infinite的解决方案);而后者则把滚动作为了window滚动的一部分(对于移动端而言,在非模态窗的场景下这种滚动更常见,共用一个滚动条也不容易引起用户的误操作)。因为笔者主要的使用场景是后者,而iscroll的解决方案虽然也能作用于页面维度的滚动,但是它需要完全替换scroll事件(相当于页面没有了scroll事件,只有touchmove事件;且此种页面在内部滚动和全局滚动的实现上有不小的难度),所以笔者在无限滚动列表上并没有使用iscroll的方案。
不过,业内虽然有现成的解决方案固然是好事,但是每种方案都有自己的特性,并不一定都合适,以react-virtualized来说,它的特性在pc上算是一个很有趣也很不错的解决方案了:
1、它构造一个“足够大”的容器来再现滚动条的实际数值;
2、它使用绝对定位来不断跟随滚动事件,改变元素的位置,几乎完美还原了正常列表的视觉,而且无论dom再多也不会卡顿;
不过,与此同时,它也有一些不足:
1、因为使用了scroll事件,某种程度上,就注定了在ios上的不足(ios scroll时会阻塞js执行),加上它的缓冲区其实是单向的(虽然这也体现了作者想尽可能节省dom的愿景),导致用户如果上下来回滚动,则很容易看到白屏;
2、由于绝对定位的“小技巧”,它要求在组件渲染之初就必须知道每一行元素的高度,但是这个看起来不起眼的小操作,却很大的影响了开发的体验(很不凑巧的笔者使用的无限列表的场景,很多情况下列表元素的高度都不能预先知道。。)
也基于以上原因,虽然react-virtualized是很不错的解决方案了,但是笔者最终没有采用。不过,在广泛借鉴了各大厂的实现之后,笔者发现,手淘列表页的实现,最简单也最有效,那么简单说下实现思路:
1、它引入了分页的概念,在用户不断刷新增加页面长度的同时,它将若干元素分为一页;
2、然后在滚动的时候计算当前滚动到了具体的哪一页,将“多余”(不需要显示,也不需要作为缓冲显示)的页的高度取出,直接赋值在容器上,然后将容器内所有元素置空;
3、当“当前页”发生变化时,动态将需要显示“空页”重新加上元素。
其实这一解决方案也有反复操作dom的性能问题,而且它并不是dom数量优化上的最优解,但是结合笔者的实际使用场景,而且结合考虑到对业务同学的api友好等各方面的,笔者最终也选择了这一实现,虽然各方面性能不是最好,但是在笔者当前的使用场景中,却最是有效的。
简单的小结一下,其实有关无限列表的实现有很多种方案,使用原生scroll事件的痛点在于ios的js阻塞问题以及如何巧妙的设计缓冲区,而使用transform模拟滚动的痛点则是有具体场景的限制和整体的重构成本,两种方案各有千秋,具体使用还需要看具体的使用场景,所以,聪明的你,告诉我?我们需要无线滚动列表么?
【js】我们需要无限滚动列表吗?的更多相关文章
- Android 高级UI设计笔记09:Android如何实现无限滚动列表
ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们提供了一个良好,整洁的用户体验 ...
- Android 高级UI设计笔记09:Android实现无限滚动列表
1. 无限滚动列表应用场景: ListView和GridView已经成为原生的Android应用实现中两个最流行的设计模式.目前,这些模式被大量的开发者使用,主要是因为他们是简单而直接的实现,同时他们 ...
- Vue组件封装之无限滚动列表
无限滚动列表:分为单步滚动和循环滚动两种方式 <template> <div class="box" :style="{width:widthX,hei ...
- 基于 Vue.js 的移动端组件库mint-ui实现无限滚动加载更多
通过多次爬坑,发现了这些监听滚动来加载更多的组件的共同点, 因为这些加载更多的方法是绑定在需要加载更多的内容的元素上的, 所以是进入页面则直接触发一次,当监听到滚动事件之后,继续加载更多, 所以对于无 ...
- 【转】超酷的 mip-infinitescroll 无限滚动(无限下拉)
写在前面 无限滚动技术(又叫做无限下拉技术)被广泛应用于新闻类,图片预览类网站.对用户来讲,使用无限滚动的页面有源源不断的信息可以预览,增加用户在页面的停留时长.技术上原理也很简单,在页面加载时加载一 ...
- jquery实现无限滚动瀑布流实现原理
现在类似于pinterest这类的表现效果很火,其实我比较中意的是他的布局效果,而不是那种瀑布流. 虽然我不是特别喜欢这种瀑布流的表现样式,但是还是写了几篇关于无限滚动瀑布流效果的文章,Infinit ...
- Jquery制作--循环滚动列表
自己模仿JQ插件的写法写了一个循环滚动列表插件,支持自定义上.下.左.右四个方向,支持平滑滚动或者间断滚动两种方式,都是通过参数设置.JQ里面有些重复的地方,暂时没想到更好的方法去精简.不过效果还是可 ...
- Infinite Scroll - jQuery & WP 无限滚动插件
无限滚动(Infinite Scroll)也称为自动分页.滚动分页和无限分页.常用在图片.文章或其它列表形式的网页中,用来在滚动网页的时候自动加载下一页的内容.Infinite Scroll 这款 ...
- LoopBar – Tap酒吧与无限滚动
相约 LoopBar – 标签栏与无限滚动为Android由Cleveroad 在Cleveroad我们最近认识到通过使用任何一个应用程序类别的导航,导航面板是很无聊和琐碎.这就是为什么我们的设计师的 ...
随机推荐
- 剑指Offer:树的子结构【26】
剑指Offer:树的子结构[26] 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路 分为两步: 第一步:在树A中找到和树B的根节点的值一 ...
- 关于node.js的安装与删除
安装node.js 先切换到root用户安装 openssl-devel su - yum install openssl-devel 下载源代码自己编译以下代码中的tar.gz包根据node.js官 ...
- 需要注意的一些Mysql语句
1. 日期处理函数:date_format() select COUNT(*) from (SELECT SERIAL_NO, APPLY_SERIAL_NO, FLAG, PAY_DATE, SEQ ...
- [zjoi2003]密码机
一台密码机按照以下的方式产生密码:首先往机器中输入一系列数,然后取出其中一部分数,将它们异或以后得到一个新数作为密码.现在请你模拟这样一台密码机的运行情况,用户通过输入控制命令来产生密码.密码机中存放 ...
- poj3461 Oulipo —— KMP
题目链接:http://poj.org/problem?id=3461 代码如下: #include<cstdio>//poj 3461 kmp #include<cstring&g ...
- llala js弹出层 颜色渐变
网址:http://bbs.csdn.net/topics/370254842
- 「网络流24题」「LuoguP3358」 最长k可重区间集问题(费用流
题目描述 对于给定的开区间集合 I 和正整数 k,计算开区间集合 I 的最长 k可重区间集的长度. 输入输出格式 输入格式: 的第 1 行有 2 个正整数 n和 k,分别表示开区间的个数和开区间的可重 ...
- 关闭页面,window.onunload事件未执行的原因
1.问题描述: JS中定义widow.onunload= function(),页面关闭时,logout()函数未执行. window.onunload = function() { logout() ...
- bzoj 1086 [SCOI2005]王室联邦——思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1086 于是去看了题解. 要回溯的时候再把自己加进栈里判断.这样才能保证剩下的可以通过自己连到 ...
- Android开发者的四大工具
1. Basic4Android Basic4Android是Android平台上一个简单而又强大的可视化快速应用开发工具,它可被用来开发和测试数据库通信,甚至可以被用来开发2D的即时游戏! 主要特性 ...