前言
大家好,我是梁木由。置信大家在咱们理论我的项目中会常常碰到*Tree* 树形控件,多层次的构造列表。大部分业务会用到可搜寻的树,进行含糊查找。那大家有没有思考过数据量在比拟大并且还能够对树进行增删改的状况下,会出现什么样的成果呢。咱们应该怎么样优化
antd tree树形控件
图例
下图一所示为antd官网的例子,图二所示为搜寻后的树后果展现
依据上图所示呢,咱们会感觉很棒呀,成果也没什么问题,立马复制粘贴到本人我的项目里。我也太棒了吧,这么利索的就实现了一个需要。
那事实如此吗?嗯,对,没错。对于没有非凡数据量的需要来说,确实能够满足。那如果要实现简单一点的性能比方能够对树进行增删改查呢,那咱们来说说会呈现哪些问题。
实现性能
- 对树减少节点
- 对树批改节点
- 对树删除节点
那对于上述三个性能,以上antd 示例,还能够满足吗,答案必定是不行,那就须要咱们在它的根底上进行二次开发,或者本人从零开始开发。
性能优化
那么首先须要想到重点是什么,还用说吗,当然是实现需要呀,那作为咱们开发人员来说,soeasy。那这个时候产品又来了,说咱们这个树呢数据量是比拟大的,咱们要思考到用户的体验。比如说呢
- 用户搜寻中呢,咱们的树后果展现须要做到,十分快的更新,不心愿用户对着loading发愣,趁此机会喝口咖啡,咱们要他全神贯注的应用咱们的零碎。
- 搜寻后呢,节点的显示以及开展要明确,无关节点及对应的父节点不须要展现,不须要出现在页面
- 并且呢用户的增删改也须要做无痕更新,
此时我不屑的眼神。
优化办法
首先呢咱们须要晓得的如何防止上述几种比拟差的体验感。咱们都晓得,树形格式化的数据都是以children进行嵌套的。那咱们须要操作某个节点时,就须要始终在递归直到获取到相应节点。那咱们只须要防止这种递归操作不就能够了吗。
如何防止呢,咱们能够将树形数据转化为扁平化的数据,只有对树进行任何操作,都在扁平化的数据中解决各种操作,而后再将扁平化数据转为树形数据就能够了,通过操作扁平化数据这种办法呢,我认为能够解决大部分的体验问题。
那么看下代码如何实现
格式化树形数据结构为扁平数据结构
/** * @description 格式化树形数据结构为扁平数据结构 * @param data 传入初始数据 * @param treeData return 的返回后果 * @param _params 替换初始数据中 key,title,children 字段为树组件中对应的字段 * @param _level 层级级别 * @param parentIds 父节点id汇合用来设置pid * @param _params.other 自定义增加须要返回的字段 */export function formatFlatTree( data, _params: any = {}, _level = 1, parentIds: string[] = [], treeData: TreeDataState[] = []) { if (!data.length) { return treeData; } const list: TreeDataState[] = []; const param = { id: _params.id || 'key', title: _params.title || 'title', children: _params.children || 'children', other: _params.other || [], }; const pIds: string[] = []; const obj = {}; for (let i = 0; i < data.length; i++) { const node = data[i]; const key = node[param.id]; const child = node[param.children] || []; if (param.other.length) { param.other.forEach((element) => { obj[element] = node[element]; }); } treeData.push({ key: key, title: node[param.title], pid: parentIds[i] || '0', level: _level, ...obj, }); list.push(...child); pIds.push(...new Array(child.length).fill(key)); } return formatFlatTree(list, param, _level + 1, pIds, treeData);}
扁平化数据转为树形数据
/** 格式化扁平数据结构为树形数据结构*/export function formatTree(list) { const data = JSON.parse(JSON.stringify(list)); const obj = {}, trees: ftDataState[] = []; data.forEach((item) => { obj[item.key] = item; }); data.forEach((item) => { const parent = obj[item.pid]; if (parent) (parent.children || (parent.children = [])).push(item); else trees.push(item); }); return trees;}