Element-ui 2.8.0版本中提升表格性能,做了哪些事情,原理是什么
背景
项目中一直用element-ui,之前用el-table的时候,发现表格数据较多时,滑动表格就会很卡。我们的表格中只有200行数据,每行大概有30的字段,表格滑动就卡的不行。在Element-ui 2.8.0版本中,对表格性能进行了优化,链接。短短只有几行代码,却解决了表格的性能问题,今天我们来深度剖析,具体是怎么做到的。
先看改变的代码

代码很简单,增加了一个watch,watch中给当前hover的dom增加"hover-row' class,之前的dom移除'hover-row'。并在214行把添加hover-row的代码去掉了。
听听了上面的我说的是不是更蒙了,很正常。那我们在再来看看具体的代码



上图的三段代码都在element-ui源码的 packages/table/src/table-body.js中。
如上图所示,table在渲染时,会调用getRowClass方法,在getRowClass方法中,会判断当前的行是不是hover的那一行,是的话就增加hover-row这个类。给每一行都增加mouseenter和mouseleave, mouseenter时把vuex中的hoverRow置为当前行,mouseleave时把hoverRow置为空。
问题出在哪?
代码表面看上去没有任何问题,但是仔细一想,只要我们把鼠标放在表格上移动,就会触发mouseenter和mouseleave,vuex中的hoveRow就会发生变化,表格就会重现渲染,render就会重新运行一次。render重新执行一次,getRowStyle有多少行就会执行多少次,getCellStyle和getCellClass(绑在单元格上的方法)有多少个单元格就会执行多少次。假设我们的表格是30*200,那么getRowStyle会执行200次,getCellStyle和getCellClass各执行6000次。还有很多绑在table上的方法都会执行。执行这么多方法,能不卡吗?
官方怎么解决

首先去掉了添加hover-row的语句。
问题:性能问题出在这里?删掉这段代码鼠标移动的时候就不会重新render?
答:问题就出在这里,删掉这段代码鼠标移动不会重新render。只要删掉这段代码,table reder的时候,this.store.states.hoverRow并不会被touch,鼠标移动的时候this.store.states.hoverRow虽然发生变化,但是并不会触发页面的重新渲染,这就是依赖收集的意义。
依赖收集:当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data

这时这段代码就更容易理解了,检测vuex中hoverRow的变化,通过直接修改dom的方法来添加类名。
问题:不是说操作dom性能不好,为什么这里要直接操作dom
答:首先直接操作dom性能是要优于vdom,因为需要把vdom转化为真实的dom,但是vdom能够批量更新,且能跨平台,数据和view分离效率也更高。如果我们只是更新单个数据,且页面重新reder很复杂时,直接操作dom也是一种解决办法。当然得看具体情况使用。
我会怎么解决这个问题
如果是我来做,我不会通过js才给一个dom hover增加样式,因为只用css就能搞定了,明明一段css就能搞定的事,为什么要用js来做
.el-table__body tr:hover {
background-color: ...;
}
总结
(1)在嵌套循环中,不要用函数,因为每次reder函数都会执行很多遍
(2)善用缓存,善用computed
Element-ui 2.8.0版本中提升表格性能,做了哪些事情,原理是什么的更多相关文章
- Python3.0版本 从听说python可以做爬虫到自己第一成功做出爬虫的经历
前言 我自己是个python小白,工作也不是软件行业,但是日常没事时喜欢捣鼓一些小玩意,自身有点C语言基础. 听说python很火,可以做出爬虫去爬一些数据图片视频之类的东东,我的兴趣一下子就来了.然 ...
- 【java规则引擎】drools6.5.0版本中kmodule.xml解析
kmodule.xml文件存放在src/main/resources/META-INF/文件夹下. <?xml version="1.0" encoding="UT ...
- vue2.0版本中v-html中过滤器的使用
Vue 2.0 不再支持在 v-html 中使用过滤器 解决方法: 1:全局方法(推荐) 2:computed 属性 3:$options.filters(推荐) 1:使用全局方法: 可以在 Vue ...
- Vmware 14.0 版本中安装Ubuntu 17.10版本无法调整分辨率的问题
装完ubuntu后发现在vmware中选择了查看-自动调整大小-自适应客户机,虚拟机也无法随着窗口大小来切换分辨率,其实是因为WAYLAND限制了. 1. 先安装vim sudo apt-get in ...
- JS中一个new到底做了哪些事情?
1.https://www.cnblogs.com/faith3/p/6209741.html 2.https://www.cnblogs.com/AaronNotes/p/6529492.html
- element ui 1.4 升级到 2.0.11
公司的框架 选取的是 花裤衩大神开源的 基于 element ui + Vue 的后台管理项目, 项目源码就不公开了,记录 分享下 步骤 1. 卸载 element ui 1.4的依赖包 2. 卸载完 ...
- Apache Flink 1.9.0版本新功能介绍
摘要:Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用的功能.目前,Apache Flink 1.9 ...
- 纪念BLives 1.0版本发布
历时两个多月的时间,BLives程序1.0发布,在开发程序期间自己经历了很多,考试,恋爱,学业,自己很纠结 很伤心,有时候很无助,为了让自己有事干,我在考试备考期间去设计程序- -#,虽然程序设计的一 ...
- 从 Bootstrap 2.x 版本升级到 3.0 版本
摘自http://v3.bootcss.com/migration/ Bootstrap 3 版本并不向后兼容 v2.x 版本.下面的章节是一份从 v2.x 版本升级到 v3.0 版本的通用指南.如需 ...
随机推荐
- 感受一把面试官通过一道题目引出的关于 TCP 的 5 个连环炮!
面试现场:从 URL 在浏览器被被输入到页面展现的过程中发生了什么? 相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式什么顺序下载?建 ...
- 将tf-faster-rcnn检测结果画在一张图像内
https://blog.csdn.net/weixin_42111393/article/details/82940681
- Mac下如何复制webp图片
将 WebP 格式图片拖到 Chrome 浏览器标签栏中(浏览器是肯定支持查看的,而且是 Google 自家的),这个时候图片是能够正常查看的.我们右键选中图片,选择「复制图片」. 打开 macO ...
- 抖音美女千千万,想用Python爬爬看
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 星安果.AirPython PS:如有需要Python学习资料的小伙 ...
- java核心技术第一篇之数据库基础
01.数据库的概念: 1).数据库的概念:数据库(Database),就是存储数据的仓库. 2).作用:用来存储和管理大量数据的.内部采用了非常便于查询的机制来存储数据,能保证我们在大量数据的情况下 ...
- MES系统在小批量电子行业生产管理中的应用
小批量电子产品生产管理的主要问题 电子电器制造类企业,既有单件小批量生产,也有批量生产:有按库存生产,也有按订单生产,属于典型的离散制造行业.因产品的不同其生产工艺流程也不尽相同,生产设备的布置不是按 ...
- iOS 多线程知识梳理
#iOS多线程知识梳理 ##线程进程基础概念 ###进程 进程是指在系统中正在运行的一个应用程序每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 ###线程 1个进程要想执行任务,必须 ...
- Android监视器概述
还望支持个人博客站:http://www.enjoytoday.cn Android监视器可帮助您分析应用程序的性能,以便您优化,调试和改进它们. 它可以让您从硬件设备或Android模拟器监控应用程 ...
- HttpClient忽略SSL证书
今天公司项目请求一个接口地址是ip格式的,如:https://120.20.xx.xxx/xx/xx,报一个SSL的错: 由于之前请求的接口地址都是域名地址,如:https://www.xxx.com ...
- 记录C#泛型
常见的泛型类型 泛型类 class MyClass<T> { //...... } 泛型接口 interface GenericInterface<T> { void Gene ...