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

原文地址:https://www.cnblogs.com/mianbaodaxia/p/11613625.html

时间: 2024-08-25 12:49:12

Element-ui 2.8.0版本中提升表格性能,做了哪些事情,原理是什么的相关文章

在Chrome 80.0版本中谷歌计划移除FTP支持

IT之家8月17日消息 日前,谷歌发文表示将从Chrome 80.0版本开始,停止对FTP支持.谷歌作出这一决定已经由来已久. 谷歌认为,FTP因为不支持加密所以存在的安全问题导致FTP更容易遭受攻击.谷歌Chrome项目工程师宣布了这一新的变化,另外,使用率低也是Chrome移除FTP功能的另一个原因.目前很多第三方FTP工具能很好的支持FTP,所以谷歌移除FTP功能也并不是没有办法被替代的. 根据谷歌此前的时间表,谷歌计划从Chrome 80.0版本开始放弃FTP支持,这一版本预计将在202

【java规则引擎】drools6.5.0版本中kmodule.xml解析

kmodule.xml文件存放在src/main/resources/META-INF/文件夹下. 1 <?xml version="1.0" encoding="UTF-8"?> 2 <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> 3 <kbase name="rules" packages="rules"> 4

jquery select2 4.0版本中,ajax请求数据无法选中

需要在processResults处理新增Id处理 var results = []; $.each(data.items, function (i, v) { var o = {}; o.id = v.itemId; o.name = v.itemName; o.value = v.itemId; results.push(o); }) return { results: results };

2.0版本中如何取得当前的控制器和方法

在 控制器 里面 1 $controllerID = Yii::$app->controller->id; 2 $actionID = Yii::$app->controller->action->id; 在 视图 里面 1$controllerID = Yii::$app->controller->id; 2$actionID = Yii::$app->controller->action->id; 原文地址:https://www.cnblo

Spark 1.0.0版本发布

前言 今天Spark终于跨出了里程碑的一步,1.0.0版本的发布标志着Spark已经进入1.0时代.1.0.0版本不仅加入了很多新特性,并且提供了更好的API支持.Spark SQL作为一个新的组件加入,支持在Spark上存储和操作结构化的数据.已有的标准库比如ML.Streaming和GraphX也得到了很大程度上的增强,对Spark和Python的接口也变得更稳定.以下是几个主要的改进点: 融合YARN的安全机制 Hadoop有着自己的安全机制,包括认证和授权.Spark现在可以和Hadoo

从 Bootstrap 2.x 版本升级到 3.0 版本

摘自http://v3.bootcss.com/migration/ Bootstrap 3 版本并不向后兼容 v2.x 版本.下面的章节是一份从 v2.x 版本升级到 v3.0 版本的通用指南.如需查看更版本更新信息,请点击 v3.0 新增内容. 主要 class 的变更 下表列举了 v2.0x 版本和 v3.0 版本之间的样式差异. Bootstrap 2.x Bootstrap 3.0 .row-fluid .row .span* .col-md-* .offset* .col-md-of

JavaScript 引擎「V8」发布 8.0 版本,内存占用量大幅下降

上周,JavaScript 引擎「V8」的开发团队在该项目官方网站上正式宣布推出最新的 8.0 版本.这次更新的重点主要集中在错误修复及性能改善上,正式的版本将在数周后随着谷歌 Chrome 80 稳定版一起发布. V8 是谷歌公司推出的开源高性能 JavaScript 引擎,主要用于提升 Web 浏览器内部 JavaScript 脚本执行的性能.V8 通过 C++ 语言编写,主要用在 Chrome 浏览器以及 Node.js 上,实现了对 ECMAScript 与 WebAssembly 的支

考勤助手ER图2.0版本所存在的问题

如图所示,考勤助手ER图2.0版本中,缺少个人信箱这一问题虽然不具有逻辑层面的问题,但是它是不满足需求的,也就是说这样的设计无法满足小组对考勤助手最初的设计.其次,就设计层面来分析,弱联系是数据库查询当中比较忌讳的一点,虽然逻辑上可行,但是在之后编程查询相关数据的时候,多表查询的访问非常不好实现,所以小组商议后决定对此进行修改.最后,就是“考勤表”的分歧,另外两位小组成员的设想是指定课次查询指定课次的出勤,但是我和组长的观点是可以查看多次课的出勤情况,这样的效果更加直观.以上就是小组讨论后发现的

Mybatis分页插件2.0版本发布

项目地址:http://git.oschina.net/free/Mybatis_PageHelper 分页插件示例: http://blog.csdn.net/isea533/article/details/24700339 v2.0更新内容: 支持Mybatis缓存,count和分页同时支持(二者同步) 修改拦截器签名,拦截Executor,签名如下: @Intercepts(@Signature(type = Executor.class, method = "query", a