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 版本的通用指南.如需 ...
随机推荐
- Wireshark 抓取USB的数据包
需要使用root权限来运行Wireshark,并利用Wireshark来嗅探USB通信数据.当然了,我们并不建议大家利用root权限来进行操作.我们可以使用Linux提供的usbmon来为我们获取和导 ...
- Vscode 打字特效插件Power Mode安装使用说明
壹 ❀ 引 我记得在17年使用atom编辑器的时候,使用过一款打字特效的插件,只要我们输入代码,代码上方就会有与代码颜色对应的星星效果,今天脑抽突然想起了这个中二插件,搜索了一番成功安装,大致效果如 ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 6
23.4 API的设计原则和规范 API是服务提供方和使用方之间对接的通道,前面我们设计的一些简单API的例子,基本上比较随意,没有使用任何规范.设想一下,每个平台都可能存在大量的API,如果API ...
- ASP.NET Core Identity 的示例
1. appsettings.json { "ConnectionStrings": { "DefaultConnection": "Server=( ...
- Nginx 转发页面跳转重定向
简介 Nginx在反向代理过程中,通过重定向跳转时会找不到URL.是因为经常没有配置Host header 的端口,需要如下标红部分一样配置端口号. 只添加Host重定向之后,就会没有端口号. 方案 ...
- Django中的response
render_to_response render_to_response('index.html', locals(),context_instance=RequestContext(request ...
- 前端之jquery2
jquery属性操作 1.html() 取出或设置html内容 // 取出html内容 var $htm = $('#div1').html(); // 设置html内容 $('#div1').htm ...
- python基础(23):面向过程与面向对象的优劣、初识面向对象
1. 面向过程与面向对象的优劣 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程 ...
- 测试工程师技术tree(“自言自语”)
理论部分 1.测试分为哪几个阶段 2.测试的流程是什么 3.如何做好测试计划 4.常见的测试用例设计方法有哪些 5.一条bug记录包含哪些内容 5.如何分层自动化测试 6.如何保证脚本的有效性 7.如 ...
- 【OOM】解决思路
一.什么是OOM? OOM就是outOfMemory,内存溢出!可能是每一个java人员都能遇到的问题!原因是堆中有太多的存活对象(GC-ROOT可达),占满了堆空间. 二.怎么解决? 1.拿到内存溢 ...