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 版本的通用指南.如需 ...
随机推荐
- Apollo的基本概念和集成实战
基本概念 使用场景 是一个分布式的配置中心.适用于微服务: 核心功能 集中管理不同环境,不同集群的配置: 配置修改后可以实时推送到应用端: 具备规范的权限,流程治理特性: 开发技术 服务端使用spri ...
- 用CSS伪类实现毛玻璃效果
效果图: 思路: 内容容器需要一个before伪类,负责引用跟背景容器相同的背景图,还需要一个after伪类,用来加上半透明的白色背景.这两个伪类的层级需都为-1,而内容容器本身的层级为1,这样做可以 ...
- HTML中引用CSS的几种方法
HTML中引用CSS的方法主要有 行内样式 内嵌式 链接式 导入样式 行内样式 指写在标签里的Style元素的值 <p style="color: #FF0000;"> ...
- 从 http协议角度解析okhttp
Okhttp 介绍 OkHttp 是 Square 公司开源的一款网络框架,封装了一个高性能的 http 请求库. 支持 spdy.http2.0.websocket 等协议 支持同步.异步请求 封装 ...
- 如果下载老版本的Xcode
打开:https://developer.apple.com/download/more/,选择符合自己的Xcode版本即可.
- 安装爬虫 scrapy 框架前提条件
安装爬虫 scrapy 框架前提条件 (不然 会 报错) pip install pypiwin32
- 访问rabbitmq-server失败
测试项目正常运行突然访问不了,各项目启动失败,查看日志发现是RabbitMQ拒绝连接. 重启后依然失败,看var/log/rabbitmq/startup_err 发现什么错误信息也没有,后查看磁盘空 ...
- SRDC - ORA-1628: Checklist of Evidence to Supply (Doc ID 1682729.1)
SRDC - ORA-1628: Checklist of Evidence to Supply (Doc ID 1682729.1) Action Plan 1. Execute srdc_db_u ...
- 苹果手机Chrome浏览器显示input:disabled时字体颜色总是为浅灰色
今天被测试人员提了个bug:苹果手机浏览器(Chrome)打开h5,控件在input:disabled的样式始终是浅灰色,要求改成黑色.测试对比:1.在多个pc浏览器上浏览input:disabled ...
- [Linux] centos6.5升级安装的supervisor
因为我要用它来管理多个PHP进程去执行任务,在默认版本下的配置多个子进程不起作用 默认版本的supervisor版本比较低2.1.9,对于运行多个子进程貌似有问题,最新版的supervisor4.1的 ...