客户又要一次性滚动千万条数据...

欸,朋友们好,我是性能优化带师,寅时码

昨天,产品发来张截图,问我怎么这么卡

我一看,噢~原来是佐田,后端的数据,有三千多条,给我挤爆了

这时间,按照传统前端的方式,应该是 减数据、截数据、分段出

引言

像是什么 虚拟列表 、动态轮播图 之类的

我之前都做过了,也发过文章讲解

这次又需要做一个 动态加载的自动滚动组件


什么意思呢?

也就是仅仅加载看得见的数据,看不见的则不生成 DOM

当然,上面那句话只是最理想的状态,以目前浏览器提供的 API 来说

无缝滚动的动态加载都是障眼法,总会有一些多余的资源

回顾其他组件的实现方式

我之前做的 动态无缝轮播 组件,实际上是加载两份相同的资源实现

当需要切换时,用点障眼法就能实现

如果需要左右都能 无缝且动态 的轮播,那么就需要复制更多资源


我做的东西基本都是通用的(懒即动力 ),也就是说,只要你需要轮播、或者滚动

那么都可以使用,他会传递个插槽给你使用

动态无缝轮播图实现,含源码

直接放源码,我给你们省流,不会用的话看看文章末尾
gitee.com/cjl2385/dig...
gitee.com/cjl2385/dig...

看我这么体贴的份上,别光收藏,点点赞呀

实现动态加载数据滚动

这里就讲点技巧吧,我实现动态加载

只有两点

  1. 两份数据,一份隐藏
  2. 找准时机,偷偷摸摸的切换数据,让人看不出来

所以重点就是这个时机,你可以利用各种事件

在用户看不见的地方切换数据

这张图里,容器的大小实际上是红色的部分

接下来,我让他滚动起来,你们就能看到效果了

很简单对吧,一个循环的动画

那么下面我变直接隐藏右边,那么就实现了

怎么样,是不是毫无破绽

讲解

  1. 准备一个数组,让他的长度,设置为用户长度的两倍
  2. 容器设置溢出隐藏,所以这时能看见的,又变成了用户指定的大小
  3. 设置一个动画,动画执行仅仅到 50% 就够了
  4. 动画设置成无限循环
  5. 监听动画的某个事件,改变数组的数据

动画如下,我写的组件比较通用,所以方向也能设置

css 复制代码
@keyframes scrollX {
    100% {
        transform: translateX(-50%);
    }
}

@keyframes scrollY {
    100% {
        transform: translateY(-50%);
    }
}

上面说了要监听事件,那要监听什么事件呢?

显然是动画迭代完一次后的动画,每次迭代都会重新运行的事件

事件名我记得住吗?我记不住

那我是怎么写的呢?

靠猜

输入一点前缀,使用快捷键呼出代码提示,然后一个个看呗

我写的快捷键大全指南

这个叫 xxx Iterate,iterate是不是很眼熟

没错,就是数组的迭代器,所以我猜就是他

那么怎么设置呢?

这里还是用老朋友,vue 的响应式 API 实现

定义一个起始索引,一个结束索引

然后用计算属性,基于他们,算出最终的数组

以后仅仅需要修改索引,大大降低开发的心智负担,大爱响应式编程

这里的 showCount 就是展示的长度,上面说了要设置成两倍

此时,仅仅需要修改起始索引,即可完成

下面的函数,在动画迭代时运行即可

这样的话,就算有上千万条数据,也仅仅会展示容器大小 * 2 的长度

还有一些简单的细节,比如鼠标移入暂停动画什么的我就不讲了

源码里已经写了

源码使用说明

代码里我用到了一个设置大小的指令 v-resize

已经放在了仓库,大家在 main.ts 把指令加入即可,比如

ts 复制代码
app.directive('resize', { ... }) // 或者使用 app.use,前提是要写成插件提供 install 方法

依赖

在文件里从 @jl-org/tool 里导入了一个函数,大家直接下载这个包即可

是我写的工具库,不想下载的话,去 npm 找,然后复制一下
www.npmjs.com/package/@jl...

代码示例

vue 复制代码
<VirtualScroll :data="data"
    style="width: 400px;"
    :speed="120"
    :item-size="100">
    <template v-slot="{ item }">
        <div class="item">{{ item.data }}</div>
    </template>
</VirtualScroll>

<script setup lang="ts">
const data = ref(Array.from({ length: 99999 }, (_, i) => ({ data: i + 1 })))
</script>

<style>
.item {
    font-size: 30px;
    background-color: lightblue;
    border: 1px solid;
    height: 100%;
    width: 100%;
}
</style>
相关推荐
强哥聊算力2 小时前
《算力江湖·英伟达传奇》第七集:ChatGPT出现前夜,英伟达发生了什么?
服务器·人工智能·算法·ai·chatgpt·gpu算力
Jmyd01234 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
砚凝霜5 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
Navigator_Z6 小时前
LeetCode //C - 1289. Minimum Falling Path Sum II
c语言·算法·leetcode
CCblandy6 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
u0111026757 小时前
JPG、PNG、WebP 怎么选?按透明度、体积和使用场景做判断
前端·javascript·vue.js·图像处理·ai作画
jerrywus7 小时前
让 AI 写完代码后交一份报告:我改造了 answer-me-with-html
前端·claude·cursor
YangYang9YangYan7 小时前
2027供应链计划校招:数学与应用数学专业如何把预测模型讲成业务决策?
人工智能·sql·算法
jsjzsl27 小时前
递归自改进系统(RSI)的本质是自发对称破缺:智能爆炸有界—— AI研发切记盲目投入
人工智能·python·算法
程序员清风8 小时前
最短路径算法:BFS、Dijkstra 与 Floyd
java·算法·宽度优先