jq 下拉加载每次只执行一次_记一次 无限列表 滚动优化

c784df551443cc8b7191eeaedff423c0.png

背景

长列表优化, 是页面性能优化中的一个比较常见的问题,也是面试中的常客。

刚好最近在的项目中, 遇到了一个长列表的性能问题,试过多种方案, 最后得以解决。

今天就给大家分享一下。

正文

场景描述

用户需要批量修改 Product中 sku 的 映射关系,可以选择的 Product 的 数量不限

每一条sku 对应如下结构:

cb3036bde68249505e8ccb4a61379f79.png

因为可以选择的sku数量是不限的, 又不能分页, 只能做到一个列表里。

于是, 长列表出现了。

刚开始的方案是做一个虚拟列表

具体就是通过监听sroll事件,每次滚动后计算一般元素位置(top和height)

然后,通过渲染三屏的方式,把一段数据渲染到页面上。

数据量不多的时候, 没什么问题。

当选择几百上千条sku 的时候, 快速滑动, 就开始出现卡顿。

如图所示:

197d64ab64c1671e2bad9a90e3be7070.gif

快速滚动出现空白

作为对比,看一下优化后的效果:

84893220ff9ed755932fcd10191c6777.gif

优化之后

问题定位

在chrome调试工具下,边拖动列表边观察dom的变化。

发现,dom的卸载/挂载/更新的情况都出奇地慢,鼠标已经停下来,能明显感觉到过一会dom才装载完成,所以很可能是dom的渲染性能问题。

定位到渲染性能有问题的dom身上,即每一个 Item(renderFakeTable)。

使用普通文本代替Item,在同样多数量的列表情况下,简单的dom明显会顺畅很多,但是,仍然会出现空白问题。

继续观察renderFakeTable中的每一个元素(可以借用devTools Profiler)。

最简单粗暴的方式就是去除某一类的组件,然后通过不断自测的方式,找出最有可能影响渲染效率的元素:

SearchSelect(基于antd的Select封装的一个业务组件)。

所以,影响渲染性能的元素很可能就是它。

渲染性能

除了组件的问题,还有可能是渲染的问题。

首先,原来无限滚动的逻辑就是基于scroll事件,通过不断滚动触发的回调,重新计算渲染到页面上的区间。

其次,为了动态调整可视区域的元素,使用了MutationObserver。

导致空白问题则会有这几种可能:

  1. 没加防抖,频繁渲染带来性能消耗
  2. scroll 和 MutationObserver 相继执行了渲染,导致dom出现了跳动的现象。
  3. 预留的元素个数,viewPrepareCount太小了,导致拖动太快时,后面或前面都没有多余的可见元素
  4. 没有开启GPU加速,应该使用transform代替top来定位到正确位置

不幸运的是,以上的可能都一一排除后,发现几乎没有啥提升。

其实,在第二点缩小范围时,应该意识到,空白问题/拖动不流畅均是因为渲染性能低下导致的

测试验证

1. 虚拟列表 rc-virtual-list

为了验证是Select 组件的问题,基于:

rc-virtual-list

做了一个在线 demo :‍‍‍‍

在线地址:https://codesandbox.io/s/optimistic-bartik-69ygc?file=/src/animation.tsx

动态演示:

38642496350c5026777cb61152c016be.gif

这里渲染了1000 条记录, 每条记录里有5个select;

默认使用的是 antd Select, 几乎拉不动;

切换到原生select之后, 如丝般顺滑。

由此可以确定,卡顿是 Slect 组件引起的。

所以要减少渲染成本:

  1. 减少自己的父组件渲染成本,React.memo/React.useMemo/React.useCallback.
  2. 减少Select渲染成本(比较麻烦,而且效果不明显。经过自测,仅仅是使用一个基础的Select,rc无限滚动的情况下同样发生了卡顿)

2. 下拉懒加载

基于 Intersection Observer 实现一个 下拉懒加载。

利用 Intersection Observer 实现:

在列表的底部(也可能是底部偏上的某个位置)插入一个observer-dom元素.

通过Observer来观测其是否在可视区域中,如果在,那么就往下加载更多的内容:

初始状态时,列表会多渲染几条数据(两屏数据),observer-dom元素一直被顶到底部.

用户往下滚动时,observer-dom元素“出现”在用户视野。

每次多加载一屏的数据,循环如此,直到整个列表都渲染到页面上。

在线demo: https://codesandbox.io/s/gundongjiazai-antd491-forked-vtchw?file=/index.js

动态演示:

d1922dcfca1f3c4b1b125ef797b6f11f.gif

选择方案

  1. 要么接受使用rc无限滚动的不够流畅;
  2. 要么使用 Intersection Observer 实现一个下拉懒加载的无限滚动效果

最终采用下拉懒加载。


总结

通常,无限滚动的方案可以分为两种:

1. 虚拟长列表

  • 优点:可以保证渲染在页面上的dom元素尽可能少

  • 缺点:如果没有特殊处理(比如rc或锁定滚动区域),快速滚动时,基本都会有闪动的情况(也就是本次的空白问题)

2. 下拉懒加载

  • 优点:防止用户快速拖动的出现闪动问题。再通过加一个loading效果,帮助优化体验

  • 缺点:当用户把列表拉到底,整个列表都会被渲染到页面上

在选择虚拟长列表or下拉懒加载之间的取舍时,可以参考:

如果闪动问题可以接受(组件渲染没有太大性能问题),而且对dom数量要求很严格,那么选择虚拟长列表会更好。

如果闪动问题不能接受,而最终的dom数量能够接受,那么选择下拉蓝加载会更好。

无论是选择虚拟长列表or下拉懒加载,在使用监听scroll事件或者Intersetion Observer API之间的取舍时,可以参考:

  • scroll的事件回调会在主线程中被成千上万次调用,尽管加了防抖
  • scroll的方式,需要不断记录scrollTop和元素高度

而使用Intersetion Observer API,上述几点的计算就可以省略了,优化工作交给了浏览器。如果不考虑IE 等, 它是一个不错的选择。

内容就这么多, 希望对大家有所启发。

如有错误, 欢迎指正, 谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql fio测试_Linux下 fio磁盘压测笔记

专业的测试磁盘IO性能的软件:1、fio 【推荐使用】2、iometerfio的使用:参考博客: http://lilinji.blog.51cto.com/5441000/1569623https://linux.die.net/man/1/fiohttp://elf8848.iteye.com/blog/2168876 【讲的比较好】注意,我…

清除浮动塌陷的4种经典套路

【自古深情留不住,总是套路得人心。】 这些日子,各个朋友圈随时可以见到这句话的身影。的确人们常说:“多一点真诚,少一点套路。”,但是最终现象写实也是那么残酷和无奈。 同样在前端攻城狮的道路,我们都是…

mysql standalone模式_Boss7 Standalone模式开发配置

PS:以下配置均添加到standalone.xml文件中。1.Get请求编码设置,将如下配置添加到标签之后2.开启开发模式:搜索“urn:jboss:domain:web:1.1”,在此标签下添加如下配置:3.虚拟域名设置搜索“urn:jboss:domain:web:1.1”&…

python ide: pycharm

1, 设置python路径 2,运行py文件 https://www.jetbrains.com/help/pycharm/2016.1/creating-and-running-your-first-python-project.html#d50296e226 3, 格式化代码 From the main menu, select Code | Reformat Code or press CtrlAltL. 转载于:https://www.cnblo…

Android 滑动菜单框架--SwipeMenuListView框架完全解析

SwipeMenuListView(滑动菜单) A swipe menu for ListView.--一个非常好的滑动菜单开源项目。 Demo 一、简介 看了挺长时间的自定义View和事件分发,想找一个项目练习下。。正好印证自己所学。 在github上找到了这个项目:SwipeMenuL…

JAVA 开发axis2_基于Apache axis2开发Java Web服务

1.安装配置axis2环境下载好后把axis2-1.4.1-war目录下面的axis2.war发布到tomcat的webapps中。发布好,访问:http://localhost:8079/axis2/ 界面如下:2.开发web服务1)创建一个java web project2)编写服务代码1 public classSampleService {23…

Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具

前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率。至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好。我个人是比较推荐使用命令行的,因为命令行是原生…

java cache-control_详解浏览器Cache-Control缓存策略

原来用的是 Expires 策略,浏览器可以直接从浏览器缓存读取数据,而无需再次请求,它的值对应一个 GMT,来告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求。例如下面的例子,这是京东的首页里找的一个,时间都干到 2027 年了…

前端必备切图ps篇

前言:当设计师通过photoshop工具设计完设计稿导出psd文件时,我们前端工程师该如何进行切图转换成网页的所需的图片呢,接下来讲讲如何利用photoshop工具快速简洁的切图,因为ps工具用到的行业很多,涉及到的各个行业&…

jenkins配置记录(2)--代码发布流程

在我们的日常运维工作中,使用jenkins来完成业务代码发版上线是至关重要的一环。前面已经提到在jenkins上添加用户权限的操作,今天重点说下如何在jenkins下构建项目工程进行代码发布? 在此简单介绍下jenkins进行代码发布的流程(根据…

autoitv3点击windows界面

在自动化测试过程中会遇到如下windows安全认证,需要输入账号和密码,这个认证对话框不属于element元素。无法用selenium操作,需要用autoitv3操作,输入账号密码后,再进行web元素操作。 有2中方式: 第一种&…

java 扩展接口_详解常用的Spring Bean扩展接口

前言Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心。Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP----开闭原则,即:1、保…

c盘java文件误删_C盘爆满怎么办,教你有选择性删除文件,恢复空间

有很多朋友说电脑c盘有很多垃圾,占着空间,还导致电脑响应变慢。还不知道能不能删除,很困扰。那么c盘文件都是什么文件呢?哪些能删除,做一次全面的清理呢?下面给大家介绍一下program Date:系统文…

java向另一activity输入_Activity经典实例一:两个Activity传递数据和对象

1、概述:Activity类直接或者间接地继承了Context、ContextWrapper、ContextThemeWrapper等基类,因此Activity可以直接调用它们的方法。创建一个Activity需要实现某些方法,常见的是实现onCreate(Bundle status)方法,该方法将会在Ac…

深入理解JSON对象

深入理解JSON对象 前面的话 json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据。2001年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式。本…

java内存分配模型优点_高并发实战(二)-并发基础 缓存 MESI 内存模型

左图为高速缓存 右图为多级缓存数据的读取和存储都经过高速缓存,CPU核心与高速缓存有一条特殊的快速通道。主存与高速缓存都是连接在系统总线上,当然其他组件也是在此基础上进行通信的。在高速缓存出现后不久,系统变得愈加复杂,高…

CentOS 7 安装SVN服务端

CentOS7下安装SVN服务 1. yum命令即可方便的完成安装# sudo yum install subversion 测试安装是否成功:# svnserve --version 更改svn的默认配置(更改默认的指向目录和默认端口)# sudo vim /etc/sysconfig/svnserve编辑示例:OPTIONS"-r /data/svn -…

.NET简谈事务、分布式事务处理

在本人的 “ .NET简谈事务本质论”一文中我们从整体上了解了事务模型,在我们脑子里能有一个全局的事务处理结构,消除对数据库事务的依赖理解,重新认识事务编程模型。 今天这篇文章我们将使用.NET C#来进行事务性编程,从浅显、简单…

css compressor java_利用YUI Compressor压缩JS/CSS之终极秘籍

JS/CSS的压缩已经不是什么新鲜话题了,自打YSlow推出后,这方面的优化话题是铺天盖地啊;不过当时作为后知后觉的我,甚至都没法完整地写出一份漂亮的JS/CSS的代码,何尝会去注意呢?!时至今日&#x…

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用

HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 HTML 列表中的dl,dt,dd,ul,li,ol区别及应用 工具/原料 html&#xff0c;dw软件方法/步骤 1无序列表 无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点&#xff08;典型的小黑圆圈&#xff09;进行标记。 无序列表始于 <…