当前位置: 首页 > news >正文

H5移动端 Vue3 + vue-virtual-scroller 实现长列表性能优化

文章目录

    • 安装 vue-virtual-scroller
    • 引入
    • 📢注意事项
    • 使用
      • 基础使用
      • 上拉加载
      • 下拉刷新

移动端在渲染长列表时 大量dom节点的渲染和重绘重排会导致页面卡顿、滚动不流畅、设备耗电加快、影响移动设备电池寿命等性能问题

这里分享使用【虚拟滚动】方案进行长列表优化,以Vue3为例,推荐使用 vue-virtual-scroller

先列举 vue-virtual-scroller 相关官方文档帮助学习

  • 官方文档
  • Live demo
  • Live demo 源码
  • Video demo

安装 vue-virtual-scroller

npm install --save vue-virtual-scroller@next
yarn add vue-virtual-scroller@next

引入

安装所有组件:

import VueVirtualScroller from 'vue-virtual-scroller'app.use(VueVirtualScroller)

按需引入组件:

import { RecycleScroller } from 'vue-virtual-scroller'app.component('RecycleScroller', RecycleScroller)

引入样式文件

import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'

📢注意事项

  1. 整个列表的高度要写死,不然会将整改列表作为可视区域,会出现渲染全部数据而不是只渲染可视区域的问题;
    这里推荐使用 flex: 1; 实现,比 height: calc(100vh - 30vw); 更优雅、更易维护
  2. 使用 -webkit-overflow-scrolling: touch; 开启硬件加速,ios高版本自带
  3. 使用 overscroll-behavior: none; 禁用iOS回弹效果

使用

使用 DynamicScroller 组件渲染不确定高度的组件

基础使用

<div class="content-wrap"><DynamicScroller:items="dataList":min-item-size="160"key-field="id"class="virtual-scroller"><template #default="{ item, index, active }"><DynamicScrollerItem:item="item":active="active":size-dependencies="[item.status, item.type]":data-index="index"class="virtual-scroller-item"><!-- 渲染组件 --><TaskItem :data="item" /></DynamicScrollerItem></template></DynamicScroller>
</div>
.icc__container {height: 100vh;display: flex;flex-direction: column;box-sizing: border-box;.icc__content-wrap {flex: 1;.virtual-scroller {/* 开启硬件加速 -webkit-overflow-scrolling: touch; ios高版本自带 */-webkit-overflow-scrolling: touch;/* 禁用回弹效果 */overscroll-behavior: none;height: 100%;}}
}

上拉加载

vant List + DynamicScroller 会导致连续触发 vant List load 事件,所以只能手写上拉加载

  1. 监听 DynamicScroller 滚动事件,如果当前距离顶部的值加上可视区域的值大于等于总高度,则滚动条触底,加载更多
  2. 使用 DynamicScroller after 插槽,定义加载中、加载完成、加载失败等状态
<div class="content-wrap"><DynamicScroller:items="dataList":min-item-size="160"key-field="id"class="virtual-scroller"@scroll="handleDynamicScrollerScroll"><template #default="{ item, index, active }"><DynamicScrollerItem:item="item":active="active":size-dependencies="[item.status, item.type]":data-index="index"class="virtual-scroller-item"><!-- 渲染组件 --><TaskItem :data="item" /></DynamicScrollerItem></template><template #after><div class="after"><van-loading v-show="loadMoreLoading">加载中...</van-loading><span v-show="finished">没有更多了</span><span v-show="loadError" @click="handleLoadMore">请求失败,点击重新加载</span></div></template></DynamicScroller>
</div>
// 上拉loading
const loadMoreLoading = ref<boolean>(false)
// 没有更多数据了
const finished = ref<boolean>(false)
// 加载失败
const loadError = ref<boolean>(false)// 实现上拉加载
const handleDynamicScrollerScroll = (e: Event) => {// 距顶部const scrollTop = (e.target as HTMLDivElement)?.scrollTop || 0// 可视区高度const clientHeight = (e.target as HTMLDivElement).clientHeight || 0// 滚动条总高度const scrollHeight = (e.target as HTMLDivElement)?.scrollHeight || 0// 触底距离const offset = 300// 如果当前距离顶部的值加上可视区域的值大于等于总高度,则滚动条触底if (scrollTop + clientHeight >= scrollHeight - offset) {if (!loadMoreLoading.value && !finished.value && !loadError.value) {console.log('滚动到底部了')loadMoreLoading.value = truehandleLoadMore()}}
}

下拉刷新

使用 vant PullRefresh实现下拉刷新

如果直接用 vant PullRefresh 包裹虚拟滚动,会导致无法向下滑动,任何位置下拉都会触发下拉刷新。

解决方案:

1. `vant PullRefresh` 中有 `disabled`  选项,可以禁用下拉刷新,默认设置为 `false`
2. 监听滚动条滚动事件中的 `scrollTop`,
3. 如果 `scrollTop` 小于4,则将 `disabled` 变为 `false`
4. 否则将 `disabled` 变为 `true`
<template><div class="container"><van-pull-refreshv-model="refreshLoading"@refresh="handlerefresh":disabled="disabledPullRefresh"class="content-wrap"><template v-if="dataList.length > 0"><DynamicScroller:items="dataList":min-item-size="160"key-field="id"class="virtual-scroller"id="virtual-scroller"@scroll="handleDynamicScrollerScroll"><template #default="{ item, index, active }"><DynamicScrollerItem:item="item":active="active":size-dependencies="[item.status, item.type]":data-index="index"class="virtual-scroller-item"><!-- 渲染组件 --><TaskItem :data="item" /></DynamicScrollerItem></template><template #after><div class="after"><van-loading v-show="loadMoreLoading">加载中...</van-loading><span v-show="finished">没有更多了</span><span v-show="loadError" @click="handleLoadMore">请求失败,点击重新加载</span></div></template></DynamicScroller></template><van-emptyv-elseimage="./no_data.png"description="暂无匹配数据":image-size="['60vw', 'auto']"class="h-80vh"/></van-pull-refresh></div><van-back-top target="#virtual-scroller" />
</template>
// 下拉loading
const refreshLoading = ref<boolean>(false)
// 禁用下拉刷新
const disabledPullRefresh = ref(false)
// 上拉loading
const loadMoreLoading = ref<boolean>(false)
// 没有更多数据了
const finished = ref<boolean>(false)
// 加载失败
const loadError = ref<boolean>(false)
// 实现上拉加载
const handleDynamicScrollerScroll = (e: Event) => {// 距顶部const scrollTop = (e.target as HTMLDivElement)?.scrollTop || 0// 可视区高度const clientHeight = (e.target as HTMLDivElement).clientHeight// 滚动条总高度const scrollHeight = (e.target as HTMLDivElement)?.scrollHeightconst offset = 300// 如果直接用 `vant PullRefresh` 包裹虚拟滚动,会导致无法向下滑动,任何位置下拉都会触发下拉刷新。// 控制是否开启下拉刷新if (scrollTop <= 4) {disabledPullRefresh.value = false} else {disabledPullRefresh.value = true}// 如果当前距离顶部的值加上可视区域的值大于等于总高度,则滚动条触底if (scrollTop + clientHeight >= scrollHeight - offset) {if (!loadMoreLoading.value && !finished.value && !loadError.value) {console.log('滚动到底部了')loadMoreLoading.value = truehandleLoadMore()}}
}

兄弟们,上面的代码在项目中踩坑实测过了!!

源码就不贴了😄

相关文章:

H5移动端 Vue3 + vue-virtual-scroller 实现长列表性能优化

文章目录 安装 vue-virtual-scroller引入&#x1f4e2;注意事项使用基础使用上拉加载下拉刷新 移动端在渲染长列表时 大量dom节点的渲染和重绘重排会导致页面卡顿、滚动不流畅、设备耗电加快、影响移动设备电池寿命等性能问题 这里分享使用【虚拟滚动】方案进行长列表优化&…...

第20章-IP路由原理

目录 1. 概述 2. 路由表 3. 查表规则 4. 路由来源类型 5. 路由优先级 6. 路由的度量值 7. 路由器写表规则 1. 概述 1. 定义 路由器:异构网络互联机制; 路由:指导路由器如何进行数据发送的路径信息; 路由表:目的地址、下一跳、出接口等; 2. IP连通的条件 沿途的每…...

SBCFormer:能够在单板计算机上以每秒1帧的速度进行全尺寸ImageNet分类的轻量级网络

文章目录 摘要1、引言2、 相关工作2.1、用于移动设备的卷积网络2.2、移动设备上的ViT和CNN-ViT混合模型2.3、评估指标 3、CNN-ViT 混合模型在低端CPU上的应用3.1、设计原则3.2、SBCFormer的整体设计3.3、SBCFormer块3.4、改进的注意力机制 4、实验结果4.1、实验设置4.2、ImageN…...

【opencv】教程代码 —features2D(8)AKAZE 特征点匹配和图像拼接

graf1.png graf3.png <?xml version"1.0"?> <opencv_storage> <H13 type_id"opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>7.6285898e-01 -2.9922929e-01 2.2567123e02…...

ssm基于springboot的数字家庭亲子视频分享网站java+vue

本网站的模块主要分为前台展示模块和后台管理模块。 前台展示模块功能如下&#xff1a; 1&#xff09;家庭照片模块 主要功能是对家庭照片的分类显示&#xff0c;如旅游、运动、生活、工作、学习等&#xff0c;每一类中的照片按时间轴展示出来。 2&#xff09;家庭亲子视频模块…...

产品经理功法修炼(1)之自我管理

点击下载《产品经理功法修炼(1)之自我管理》 1. 前言 产品经理的能力修炼并非局限于某一技能的速成,而是需要全面参与到产品的整个生命周期中,通过不断的实践来逐步提升自己的各项能力。尽管在企业的日常运作中,我们不可能身兼数职去扮演每一个角色,但作为产品的核心负…...

2024年04月IDE流行度最新排名

点击查看最新IDE流行度最新排名&#xff08;每月更新&#xff09; 2024年04月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多&#xff0c;这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&am…...

17.应用负载压力测试

早些点&#xff0c;下午题考&#xff0c;最近几年出现的少&#xff1b; 备考较为简单&#xff1b;历年真题相似度高&#xff1b; 主要议题&#xff1a; 1.负载压力测试概述 注意这些测试细微的差别&#xff1b; 负载测试和压力测试的方法比较相似&#xff0c;但是目的不同&a…...

Gauss到底是不是国产数据库

华为GaussDB数据库深度解析 引言 在数字化转型的浪潮中&#xff0c;数据成为企业最宝贵的资产之一。如何高效地管理和利用这些数据&#xff0c;成为企业面临的一大挑战。数据库作为数据存储和管理的核心系统&#xff0c;其性能、安全性、可用性和扩展性等特性直接影响到企业的…...

spark sql执行引擎原理及配置

如果我们想要给上层开发人员配置好一个统一的sql开发界面&#xff0c;让他们统一通过sql开发即可&#xff0c;可通过spark中的thriftserver服务实现&#xff0c;与hive中的thriftserver类似&#xff0c;配置好该服务后&#xff0c;上层通过db client或者代码中通过jdbc连接即可…...

【C语言基础】:自定义类型(二) -->联合和枚举

文章目录 一、联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员的结构体和联合体对比1.4 联合体大小的计算1.5 联合体练习 二、枚举类型2.1 枚举类型的声明2.2 枚举的优点 书山有路勤为径&#xff0c;学海无涯苦作舟。 创作不易&#xff0c;宝子们&#xff01;如果这篇…...

【授时防火墙】GPS北斗卫星授时信号安全防护装置系统

【授时防火墙】GPS北斗卫星授时信号安全防护装置系统 【授时防火墙】GPS北斗卫星授时信号安全防护装置系统 1、装置概述 卫星信号安全防护装置&#xff08;以下简称“防护装置”&#xff09;是一款专门针对卫星导航授时安全的设备。该设备能接收 BD 系统和 GPS 系统卫星信号&am…...

关于 MySQL 优化(详解)

文章目录 关于 MySQL 优化一、硬件方面的优化1、关于 CPU2、关于内存3、关于磁盘 二、MySQL 配置文件1、 default-time-zone8:002、interactive_timeout 1203、wait_timeout 1204、open_files_limit 102405、group_concat_max_len 1024006、usermysql7、character-set-serv…...

Hive详解(5)

Hive 窗口函数 案例 需求&#xff1a;连续三天登陆的用户数据 步骤&#xff1a; -- 建表 create table logins (username string,log_date string ) row format delimited fields terminated by ; -- 加载数据 load data local inpath /opt/hive_data/login into table log…...

阿里云效codeup如何执行github flow工作流

在阿里云效中执行 GitHub 工作流&#xff0c;实质上是在使用 Git 进行版本控制的过程中遵循 GitHub Flow 的原则。GitHub Flow 是一种简洁高效的工作流程&#xff0c;特别适用于追求快速迭代的团队。下面是在阿里云效中执行 GitHub 工作流的基本步骤&#xff1a; 1. 准备工作 …...

node.js的模块化 与 CommonJS规范

一、node.js的模块化 (1)什么是模块化&#xff1f; 将一个复杂的程序文件依据一定的规则拆分成为多个文件的过程就是模块化 在node.js中&#xff0c;模块化是指把一个大文件拆分成独立并且相互依赖的多个小模块&#xff0c;将每个js文件被认为单独的一个模块&#xff1b;模块…...

RK3588平台开发系列讲解(PWM开发篇)

目录 前⾔ 驱动文件 DTS 节点配置 PWM 流程 PWM 使⽤ 常⻅问题 PWM 在 U-Boot 与 kernel 之间的衔接问题 PWM Regulator 时 PWM pin 脚上下拉配置问题 前⾔ 脉宽调制&#xff08; PWM &#xff0c; Pulse Width Modulation &#xff09;功能在嵌⼊式系统中是⾮常常⻅的…...

宝塔面板操作一个服务器域名部署多个网站

此处记录IP一样&#xff0c;端口不一样的操作方式&#xff1a; 宝塔面板操作&#xff1a; 1、创建第一个网站&#xff1a; 网站名用IP地址&#xff0c;默认80端口。 创建好后&#xff0c;直接IP访问就可以了。看到自带的默认首页 2、接下来部署第二个网站&#xff1a; 仍然是…...

surfer绘制等值线图

surfer介绍 Surfer软件&#xff0c;是美国Golden Software公司编制的一款以画三维图的软件。该软件具有强大的插值功能和绘制图件能力&#xff0c;可用来处理XYZ数据&#xff0c;是地质工作者常用的专业成图软件&#xff08;来源于百度百科&#xff09;。 surfer可以用来绘制…...

免费开源的 AI 绘图工具 ImgPilot

免费开源的 AI 绘图工具 ImgPilot 分类 开源分享 项目名: ImgPilot -- 通过提示词及涂鸦生成图片 Github 开源地址&#xff1a; GitHub - leptonai/imgpilot: Turn the draft into amazing artwork with the power of Real-Time Latent Consistency Model 在线地址&#xff…...

Java系统架构设计:构建稳定高效的软件基石

在当今数字化时代&#xff0c;软件系统的稳定性、可扩展性和性能至关重要。Java作为一种广泛应用的编程语言&#xff0c;其系统架构设计对于软件的成功实施具有决定性的影响。本文将探讨Java系统架构设计的重要性以及设计过程中的关键要素。 首先&#xff0c;Java系统架构设计…...

【IntermLM2】学习笔记

微调方式 在大模型的下游应用中&#xff0c;可以有两种微调方式 增量续训 即无监督的方式&#xff0c;让模型学习一些新知识&#xff0c;比如某些垂直领域的新知识 使用的数据有&#xff1a;书籍&#xff0c;文章&#xff0c;代码等有监督微调 为了让模型学会理解指令进行对话…...

【二叉树】Leetcode 230. 二叉搜索树中第K小的元素【中等】

二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1a;1 解…...

JS中常用的几种事件

在js中分为多种事件&#xff0c;比如点击事件&#xff0c;焦点事件&#xff0c;加载事件&#xff0c;鼠标事件等等... ... 点击事件 onclick点击事件&#xff0c;ondblclick双击事件 焦点事件 onblur元素失去焦点&#xff0c;onfocus元素获取焦点 加载事件 onload一个页面…...

Android WebView的使用与后退键处理

目录 前言首先&#xff0c;我们需要在布局文件中添加webView组件在Activity中获取webView实例&#xff0c;并加载网页内容 前言 webView是Android中常用的组件之一&#xff0c;用于展示网页内容。它可以加载HTML文件、URL链接等网页内容&#xff0c;并提供交互功能。在使用webV…...

【备忘录】Docker 2375远程端口安全漏洞解决

最近为了项目需要&#xff0c;把docker 的远程端口2375 给开放了。不出意外出意外了。没多久&#xff0c;网站报流量告警&#xff0c;第一反应就是开放2375这个端口问题导致&#xff0c;毫不迟疑直接切换服务器。关闭该台服务器的docker服务&#xff0c;并逐步清理掉挖矿进程&a…...

343. 整数拆分(力扣LeetCode)

文章目录 343. 整数拆分题目描述动态规划 343. 整数拆分 题目描述 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释:…...

Spring面试题系列-3

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而&#xff0c;Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言&#xff0c;绝大部分Java应用都可以从Spring中受益。 Spring的属性…...

【比特币】比特币的奥秘、禁令的深层逻辑与风云变幻

导语&#xff1a; 比特币(Bitcoin)&#xff0c;这个充满神秘色彩的数字货币&#xff0c;自诞生以来便成为各界瞩目的焦点。它背后所蕴含的Mining机制、禁令背后的深层逻辑以及市场的风云变幻&#xff0c;都让人欲罢不能。今天&#xff0c;我们将深入挖掘比特币的每一个角落&…...

【情感分析概述】

文章目录 一、情感极性分析概述1. 定义2. 情感极性的类别3. 应用场景 二、情感极性分析的技术方法1. 基于规则的方法a. 关键词打分b. 情感词典的使用 2. 基于机器学习的方法a. 监督学习方法b. 深度学习方法 三、Python进行情感极性分析 一、情感极性分析概述 情感极性分析&…...

怎么做下载类网站/新手运营从哪开始学

是“Block Started bySymbol”的缩写&#xff0c;意为“以符号开始的块”。 BSS是Unix链接器产生的未初始化数据段。其他的段分别是包含程序代码的“text”段和包含已初始化数据的“data”段。BSS段的变量只有名称和大小却没有值。此名后来被许多文件格式使用&#xff0c;包括P…...

最好的微网站建设公司/广告关键词排名

首先先说下bugly的崩溃统计是实时的&#xff0c;即你的app前脚崩溃&#xff0c;bugly后脚就会给你统计到&#xff0c;但是在统计崩溃信息的时候有的时候可能只给你记录了一个简单的崩溃信息&#xff0c;并不能详细的告诉你哪个类的哪个方法的哪行导致了app的崩溃&#xff0c;而…...

软件开发和网站建设/微信平台推广方法

命令简介&#xff1a; 该命令用来识别文件类型&#xff0c;也可用来辨别一些文件的编码格式。它是通过查看文件的头部信息来获取文件类型&#xff0c;而不是像Windows通过扩展名来确定文件类型的。 执行权限 &#xff1a;All User 指令所在路径&#xff1a;/usr/bin/file 命令语…...

网站编辑建设/b2b电子商务平台排名

老孟导读&#xff1a;前2天有读者问到是否有带分页功能的表格控件&#xff0c;今天分页功能的表格控件详细解析来来。PaginatedDataTablePaginatedDataTable是一个带分页功能的DataTable&#xff0c;生成一批数据&#xff0c;项目中此一般通过服务器获取&#xff0c;定义model类…...

网站获取用户/google代理

在其他语言中为了避免类和方法重名问题&#xff0c;都有一个类似命名空间的概念&#xff0c;在js中实现类似的功能吗&#xff1f; 可以实现&#xff0c;主要是借助于js中对象的概念来实现&#xff0c;例如&#xff1a; 1 在命名空间中定义方法属性 var GiantCorp GiantCorp||{…...

企业做的网站开发费如何入帐/软文写作实训总结

#26 删除排序数组中的重复项给定一个 排序数组 &#xff0c;你需要在原地删除重复出现的元素&#xff0c;使得每个元素只出现- -次,返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组并在使用0(1)额外空间的条件下完成。1)算法思路先判断…...