小帅の技术博客 小帅の技术博客
首页
  • 前端
  • 服务
  • Node
  • 技术
  • 服务器
  • 程序猿
关于
友链
  • 网站
  • 资源
  • Vue资源
  • 优秀技术文章
  • 分类
  • 标签
  • 归档
GitHub

前端小帅

学而不思则罔,思而不学则殆
首页
  • 前端
  • 服务
  • Node
  • 技术
  • 服务器
  • 程序猿
关于
友链
  • 网站
  • 资源
  • Vue资源
  • 优秀技术文章
  • 分类
  • 标签
  • 归档
GitHub
  • 前端

    • JavaScript

    • webpack

    • Vite

    • rollup

    • react

    • vue

      • vue3使用总结
      • vue编译为js的研究
      • 虚拟列表
        • 前言
        • 背景
        • 分析
        • 实战
    • monorepo

    • 性能爆表的solidjs
    • 项目开发的一些思考
    • 多级别权限设计思考及实战
    • 浏览器中JavaScript的运行机制
    • WebSocket连接过程及原理分析
  • NodeJs

  • 服务

  • 其他

  • 2021年终总结
  • 2022年终总结
  • 文章
  • 前端
  • vue
sunss
2023-03-30

虚拟列表——你需要知道的优雅处理大数据渲染的技巧

2023年了,你还不会高性能渲染吗?1万?10万?条数据,根本不怂,虚拟列表高性能渲染实战!

# 前言

按照我们常规理解,数据量较大时一般都是通过分页进行解决处理,对于Table组件类这种列表展示我们应该很熟悉了。

分页可以实现最小化接口数据量,后端根据前端传入的参数,返回指定的范围数据。毕竟我给你1000条数据,你也很难用一屏把全部数据展示出来(问就是“优雅”🤡)

就一般场景而言,以后端分页为主。但是,也不排除一些特殊业务场景,需要返回大量数据的情况(问就是“业务场景”需要🤡)

这里我们主要讨论长列表的场景,当存在在大量数据返回的情况下(如 Select 组件),如何优雅的高性能渲染

# 背景

结合我司实际使用场景为例:

有这样一个类似 Input + Select 组件的高级业务封装组件,可选列表数据根据输入内容动态变化,每一项嵌套有多个div、span标签以及img等元素,整个容器元素会频繁关闭、开启,触发重新渲染,需要渲染的字典数据接口是全部返回的,一般是600条以上。

简单分析下:

  1. 接口返回数据量较大,考虑到列表每一项存在多个嵌套标签元素,在创建节点、渲染数据的时候会比较消耗性能
  2. 列表数据动态变化、频繁开关,这意味着整个元素会频繁触发创建节点、渲染的流程

# 分析

为了更加清晰的表现出耗时瓶颈,这里我以1万条数据为例,分析创建一万个节点的消耗占比

infiniteList-1

根据耗时结果,分析可得出:

  1. js运行时间为23ms,还是比较快的
  2. 总运行时间达到了739ms,耗时比较明显

这俩耗时差距明显,我们需要思考下发生了什么

总所周知,JS的运行是单线程的,浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染,流程大致是这样🤓

task->渲染->task->...

如果存在微任务的话,则是这样子🧐

宏任务 -> 微任务 -> 渲染 -> 下一个任务...

具体细节不再赘述,详情参见我的这篇文章 从宏观层面理解——浏览器中JavaScript的运行机制

infiniteList-2

根据JavaScript的执行逻辑,结合Chrome performance工具可以进一步分析得出如下结果:

耗时主要集中在 Rendening,为688ms,占比高达 93%。进一步查看performance,可以发现Recalculate Style(样式重新计算)与Layout(布局)的耗时占比,可以确定性能瓶颈主要集中在 渲染 这一步。

这是没有经过任何优化处理的代码,在拿到10000条数据后,我们直接创建10000个DOM节点。

假如弹窗的宽高是固定的,如果弹窗内只能展示20条数据,接口返回给了10000条数据,那么创建10000个DOM节点再全部渲染是完全没必要的,就像做图片懒加载一样,我们可以在页面滚动到可视区域的时候再渲染对应的图片。

因此,我们应该如何优化?

首先要考虑的应该是尽量做到最小开销的渲染。那么答案就很明显了,减少节点的创建,进而减少布局的渲染消耗。

# 实战

编辑
#vue
上次更新: 2023/04/26, 10:07:14
vue编译为js的研究
【前端组件化】系列第一篇

← vue编译为js的研究 【前端组件化】系列第一篇→

最近更新
01
2022年终总结(技术篇)
02-14
02
vue编译为js的研究
12-07
03
【配置文件分析】——json、yaml、toml
09-06
更多文章>
sunss | © 2020.08-2023.04 浙ICP备2022002957号-1
载入天数... 载入时分秒...  |  总访问量 次
提供CDN加速/云存储服务
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式