性能优化 | el-table中内嵌大量el-input控件导致渲染卡顿的问题

场景

项目中有一个应用场景,用户需要在表单中大量使用选择框以及输入框填写数据(每一行大概有三十几个输入框),当选择框与输入框达到一定数量的时候,页面会出现输入不连续、卡顿的现象,如下图:
需求原型.png

排查

查了一下网上的解决方案,大体是因为页面渲染过多的el-input输入框给浏览器带来较大的渲染压力导致的。基于这点,对项目作出优化。

引入虚拟表格

虚拟表格,简单来说就是页面并不渲染表格中的所有数据,只渲染可视窗口部分的数据,当用户拖动滚动条滚动的时候,逐渐加载数据。这个适用于表格中需要渲染大量数据的场景,从而减轻浏览器的渲染压力。

对于elementui中使用el-table加入虚拟列表,可以参考下面这篇文章:
element全网最简单el-table实现虚拟列表

参考上面的文章,做了一个初版的效果。但由于虚拟列表只渲染部分数据的特性,所以一定会带来一个缺陷,那就是会短暂出现白屏的问题,即用户看到未渲染的区域。排查原因得知是因为el-table的占位区域append设置为定高totalHeight

<!-- 占位 -->
<template #append>
  <div :style="{ height: `${totalHeight}px` }"></div>
</template>

...
totalHeight() {
  return this.tableData.length * this.itemHeight
}

经过思考,改成动态变化的高度,从而形成一种滚动触底更新的效果:

// 改变append的高度
updated() {
  if (this.$refs.multipleTable) {
    const bodyEl = this.$refs.multipleTable.$el.getElementsByTagName("tbody")[0]
    if (bodyEl.offsetHeight) {
      this.totalHeight = bodyEl.offsetHeight
    } else if (bodyEl.offsetHeight === 0 && this.tableData.length === 0) {
      this.totalHeight = 0
    }
    // 重新绘制表格
    this.$refs.multipleTable.doLayout()
  }
},

虚拟表格再优化

引入虚拟表格后,加载确实快不少,输入卡顿的显现也明显优化。但发现一个问题,原有的选择方法不生效,当用户滚动的时候,原有的选择项被清空。那么,如何记录选择列表的状态呢?elementui提供了一个reserve-selection的API,用于记录列表项的选择状态:
reserve-selection.png

当然,也需要重写@select="handleSelect"@select-all="handleSelectAll"方法:

// 监听选择全部
handleSelectAll() {
  if (this.isSelectAll) {
    this.tableData.forEach(item => {
      this.$refs.multipleTable.toggleRowSelection(item, false)
    })
    this.selectList = []
    this.isSelectAll = false
  } else {
    this.tableData.forEach(item => {
      this.$refs.multipleTable.toggleRowSelection(item, true)
    })
    this.selectList = this.tableData
    this.isSelectAll = true
  }
},
// 手动触发选择事件
handleSelect(selection) {
  this.selectList = selection
  if (selection.length === this.tableData.length) {
    this.isSelectAll = true
  } else {
    this.isSelectAll = false
  }
},

引入虚拟输入框

引入虚拟列表后,效果确实提升了不少,至少在大数据量的情况下,不再会出现卡顿了(因为大数据量其实只渲染固定的数据)。但还有可以优化的空间吗?
我们之前提到,造成页面卡顿的原因,就是大量渲染了el-input以及el-select控件。那么,可以再进一步优化,以减少控件的渲染数量吗?我在这篇文章中找到了灵感:
vue大数据表格卡顿问题的完美解决方案
或者直接看文章提到的demo:
Demo
DEMO.png
核心思路就是,**只有当需要编辑的时候,才显示输入框,其余都显示内容。**这么一来,最多只会渲染1个编辑控件,卡顿问题可以进一步得到优化。

实现思路

  • template中根据条件选择渲染编辑控件,默认显示表格内容(同时通过修改样式模拟输入框必填标红);
  • 鼠标点击表格的时候,记录当前表格的坐标,用于切换编辑控件;
  • 页面根据渲染条件,切换编辑控件,同时自动聚焦到编辑框中。

示例代码如下所示:

<el-form-item :prop="'displayList.' + $index + '.出差地点'">
  <el-input v-if="focusCell === `${$index}-出差地点`" type="textarea" v-model="row['出差地点']" @blur="beforeComputedAll" autosize></el-input>
  <div v-else :class="row['出差地点'] ? 'm-input' : 'custom-required'">{{ row['出差地点'] }}</div>
</el-form-item>

记录表格坐标可以使用el-table的@cell-click方法:

// 聚焦单元格
updateFocusCell(row, col, cell) {
  if (this.focusDebounce) {
    clearTimeout(this.focusDebounce)
    this.focusDebounce = null
  }
  this.focusDebounce = setTimeout(() => {
    const lineNo = row['行号']
    const prop = col.property
    const idx = this.displayList.findIndex(item => item['行号'] === lineNo)
    if (this.focusCell !== `${idx}-${prop}`) {
      this.focusCell = `${idx}-${prop}`
      this.$nextTick(() => {
        target.focus()
      })
    }
    this.focusDebounce = null
  }, 20)
},

最终效果

最终效果.jpg

总结

至此,表格已经从一开始的输入卡顿,到现在基本是可以流畅输入了,使用体验得到大大的提升。当然还有优化的空间,比如校验逻辑的编写,以及一些相关的计算等等,那块就是属于算法层面的东西了,在此就不展开叙述。
对于表格大批量数据渲染的优化方案,总结如下:

  • 引入虚拟列表,只渲染可视化区域的数据;
  • 模拟编辑控件,仅在需要编辑的时候才展示;
  • 计算逻辑优化,减少计算时间。

第一次遇到这种类型的优化,觉得挺有意思的,在此做一个记录。如果大家有更好的优化方案也可以在评论区提出,欢迎大家一起学习~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LoRa无线通讯入门

本文图片来自于深入浅出讲解LoRa通信技术&#xff0c;LoRa技术介绍&#xff0c;LoRa开发与应用&#xff0c;物联网学习必备知识点&#xff01;_哔哩哔哩_bilibili LoRa无线通讯 LoRa&#xff08;Long Range&#xff09;是一种低功耗广域网&#xff08;LPWAN&#xff09;技术&a…

【春招特供】Unity面试题总结 | Unity基础篇

物体发生碰撞的必要条件&#xff1f; 两个物体都必须带有碰撞器&#xff08;Collider&#xff09;&#xff0c;其中一个物体还必须带有Rigidbody刚体&#xff0c;而且必须是运动的物体带有Rigidbody脚本才能检测到碰撞。 2. Unity3d中的碰撞器和触发器的区别&#xff1f; 碰…

颠覆传统?「一束光子,两种频率」的量子纠缠!

在最新的研究中&#xff0c;科学家们开发了一种革命性的量子纠缠方式——“频域光子数路纠缠”&#xff08;frequency-domain photon number-path entanglement&#xff09;。这一量子物理学的重大进展涉及到一个创新性的工具&#xff1a;频率分束器&#xff08;frequency beam…

B2985A是德科技B2985A高阻计

181/2461/8938产品概述&#xff1a; B2985A 静电计/高阻表 描述 B2985A 静电计/高阻表是全球少有具有图形显示功能的静电计&#xff0c;可凭借 0.01 fA&#xff08;0.01 x 10-15 A&#xff09;的分辨率帮助您可靠测量弱电流&#xff0c;并可测量高达 10 PΩ&#xff08;10 x 1…

[leetcode] 62. 不同路径

文章目录 题目描述解题方法方法一&#xff1a;动态规划java代码复杂度分析 方法二&#xff1a;排列组合java代码复杂度分析 相似题目 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右…

毕业设计:《基于 Prometheus 和 ELK 的基础平台监控系统设计与实现》

前言 《基于 Prometheus 和 ELK 的基础平台监控系统设计与实现》&#xff0c;这是我在本科阶段的毕业设计&#xff0c;通过引入 Prometheus 和 ELK 架构实现企业对指标与日志的全方位监控。并且基于云原生&#xff0c;使用容器化持续集成部署的开发方式&#xff0c;通过 Sprin…

开源模型应用落地-CodeQwen模型小试-SQL专家测试(二)

一、前言 代码专家模型是基于人工智能的先进技术&#xff0c;它能够自动分析和理解大量的代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&…

使用Bandzip分卷压缩文件

需求 部分文件太大&#xff0c;例如超过10G&#xff0c;就不能使用企业微信等传输&#xff0c;如果可以把一个10G的文件分割成为10个1G的文件就可以方便传输了。 实现方式 使用bandzip&#xff0c;把超过10G的文件分卷压缩成为多个小的zip文件。 把生成的多个文件放在同一目…

网红隋总揭秘:高效实施人力RPO项目的秘诀

随着企业对于招聘流程效率和专业性的追求日益提升&#xff0c;RPO(招聘流程外包)项目逐渐成为人力资源领域的热门话题。隋总凭借丰富的行业经验和独特的视角&#xff0c;分享了关于如何高效实施人力RPO项目的秘诀。 一、明确目标&#xff0c;找准定位 在启动RPO项目之前&#x…

零基础入门篇④ 初识Python(注释、编码规范、关键字...)

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏订阅地址 👉Python从…

【挑战30天首通《谷粒商城》】-【第一天】01、简介-项目介绍

文章目录 课程介绍一、 项目介绍1、项目背景A、电商模式1、B2B 模式2、B2C 模式3、C2B 模式4、C2C 模式5、O2O 模式 1.2、项目架构图1.3、项目技术 & 特色1.4、项目前置要求二、分布式基础概念(略)三、环境撘建(略) one more thing 课程介绍 1.分布式基础(全栈开发篇)2.分…

UE5 audio capture 回声问题 ||在安卓上有爆鸣声

参考视频 0.基本步骤 【UE4_蓝图】录制麦克风声音/系统声音并输出保存WAV文件_ue4录音-CSDN博客 1.步骤 1.创建Sound Submix A 2. 右键新建Sound Submix B 3.把B的两个参数调为-96 4.audio capture的Base Submix&#xff0c;把前面提到的A赋值进去 5.开始录制输出和完成录制…

【Unity 协程】

Unity中的协程&#xff08;Coroutine&#xff09;是一种编程结构&#xff0c;它允许你以一种看似同步的方式编写可能需要异步执行的代码。协程特别适用于需要在一定时间后执行操作&#xff0c;或者在循环执行某段代码直到某个条件满足时的场景。 协程使用IEnumerator委托来实现…

30天精通 Δ-Σ ADC 设计

在现代电子工程和信号处理领域&#xff0c;模拟-数字转换器&#xff08;ADC&#xff09;是实现信号精确转换的核心组件。ADC技术正经历革新&#xff0c;拓展了其在多个前沿技术领域的应用范围。 **首先&#xff0c;**ADC的采样率和分辨率是衡量其性能的关键指标。随着技术工艺…

海外网安同行们面对当下的就业环境,也破防了。。。

问&#xff1a;漂亮国的安全行业就业市场怎么样&#xff1f; 答&#xff1a;初级岗位挺好找的&#xff0c;如果你有一个硕士学位并且还有10年工作经验的话。 0x00 我之前在分析海外的就业环境的时候[海外安全行业工资水平怎么样&#xff1f;]&#xff0c;一度以为外国的月亮就…

分布式光伏管理系统和一般的光伏管理系统相比有什么区别?

随着全球对可再生能源的关注度日益提高&#xff0c;光伏技术作为其中的佼佼者&#xff0c;已经得到了广泛的应用。在光伏技术中&#xff0c;管理系统扮演着至关重要的角色&#xff0c;它关乎着光伏电站的运行效率、能源产出以及运维成本等多个方面。其中&#xff0c;分布式光伏…

N9048B PXE EMI 测试接收机,1 Hz 至 44 GHz

​ _EMI_ N9048B EMI 测试接收机 1 Hz 至 44 GHz Keysight N9048B PXE 是一款符合标准的 EMI 测试接收机&#xff0c;配有射频预选器和 LNA 设计。其实时扫描&#xff08;RTS&#xff09;功能有助于您缩短总体测试时间&#xff0c;轻松执行无间隙的信号捕获和分析。 特点 …

前后端功能实现——添加品牌

需求 点击新增&#xff0c;跳转到添加品牌的页面&#xff0c;从后一个页面提交品牌数据&#xff1a; 1、BrandMapper接口添加add()方法 /** * 添加品牌 */ void add(Brand brand); 2、BrandMapper.xml中添加sql方法 <insert id"add">insert into brand val…

【字符串】Leetcode 最长回文子串

题目讲解 5. 最长回文子串 算法讲解 dp[i][j]表示i~j这一段区间的子串是否是回文 当s[i] s[j]的时候&#xff0c;此时是有三种情况的&#xff1a; ij说明一个字符肯定是回文 i1 j也说明一个字符是回文 i1 < j说明需要判断[i1, j-1]这一段区间是否是回文 此时我们就可以…

代码随想录算法训练营第十三天:树的认知(补五一)

代码随想录算法训练营第十三天&#xff1a;树的认知&#xff08;补五一&#xff09; ‍ 二叉树的递归遍历 #算法公开课 《代码随想录》算法视频公开课 ****(opens new window)****​ &#xff1a;​每次写递归都要靠直觉&#xff1f; 这次带你学透二叉树的递归遍历&#xf…