【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我们最近认识到通过使用任何一个应用程序类别的导航,导航面板是很无聊和琐碎.这就是为什么我们的设计师的 ...
随机推荐
- Java 获取当前日期和时间
原文地址:http://www.blogjava.net/parable-myth/archive/2013/01/17/394364.html 有三种方法: 方法一:用java.util.Date类 ...
- linux3 源代码安装
源代码安装: 通过yum就不会有依赖关系(安装mysql是安装mysqlServer).Rpm更新的时候,如果没有安装软件就回去安装. 应用程序和系统命令会放在不同的目录中(bin,sbin,usr/ ...
- Linux下MySQL、Apache、PHP源码安装全程实录(CentOS 6.4)
转自http://www.zjmainstay.cn/lamp-config 本文记录了我自己配置LAMP的全过程,借此记录一下,同时希望能够帮助一下需要帮助的LINUX新人,跟我一起学习,一起进步. ...
- vue指令与$nextTick 操作DOM的不同之处
异步更新队列 可能你还没有注意到,Vue 异步执行 DOM 更新.只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变.如果同一个 watcher 被多次触发,只会被推 ...
- 关于MySQL的information_schema库简单介绍及实际应用
本文简介 写本文主要是围绕下面几点进行的. 1.information_schema数据库到底是做什么用的? 2.执行alter table 表名 modify column 字段名 类型 这个sql ...
- Codeforces Round #369 (Div. 2) D. Directed Roads —— DFS找环 + 快速幂
题目链接:http://codeforces.com/problemset/problem/711/D D. Directed Roads time limit per test 2 seconds ...
- Codeforces Round #374 (Div. 2) A. One-dimensional Japanese Crossword —— 基础题
题目链接:http://codeforces.com/contest/721/problem/A A. One-dimensional Japanese Crossword time limit pe ...
- Appium基础——one demo
启动模拟器,启动appium android avd启动模拟器管理 选择一个版本启动 安装appium-client 直接pip install appium-python-client安装 ...
- 【应用】SVG饼状图
<!DOCTYPE html> <html> <head> <title></title> </head> <body o ...
- python中format()方法格式化字符串
format()是python2.6新增的一个格式化字符串的方法,功能非常强大,有可能在未来完全替代%格式化方法,相比 % ,format()的优点有: 1 .格式化时不用关心数据类型的问题,form ...