前端对jQuery的jsTree插件的大量数据处理性能优化实践(加载速度优化)

自己的jsTree性能优化实践,希望给大家提供一个思路

系统使用jstree做的树形展示,开始的数据量有3000左右,生成树的时间很快,但是后来需要加到50000条数据,jstree插件形成树很慢,并且会导致页面卡顿,测试发现5000条数据从请求到树的生成需要大概5秒,30000条数据大概需要15秒,50000条数据要30秒左右,于是对jstree大量数据进行优化。

通过各种尝试,看国外文档,看jsTree源码,阅读jsTree文档,最终尝试得到jstree中 _append_json_data  方法效果最好,不会导致页面卡顿无法点击的情况。

jsTree大量数据实现思路(先加载父节点展示出来,再加载子节点的大量数据append进去):

1、先请求父节点数据(本系统中公司名称为父节点),通过jsTree先展示出来,形成只有公司名的树,这个数据不多,先展示出来,提高用户的体验。大致代码如下:

$('#factoryDeviceTree').jstree({
		"core": {
			'data': function (obj, callback) {
				var jsonstr = "[]";
				var jsonarray = eval('(' + jsonstr + ')');
				var url = 'xxxxxxxxxxxx/xxxxxxxxx';
				$.ajax({
					type: "POST",
					url: sys.rootPath + url,
					dataType: "json",
					cache: false,
					success: function (data) {
						
						jsonarray = result;
						

						callback.call(this, jsonarray);
						
					}.bind(this)
				});
			}.bind(this),
			"themes": {
				"responsive": true,
			},
			"multiple": true,
			"animation": 200,
			"dblclick_toggle": true,
			"check_callback":true,
			"expand_selected_onload":false
		},
		
		"progressive_render":true,
		"checkbox": {
			"keep_selected_style": false,
			"cascade":"down",
			"three_state": true, //父子级别级联选择
			"cascade_to_hidden":"false"
		},
		"plugins": ["search","checkbox"]
	})

2、页面ready的时候就请求公司对应的子节点的数据,这个数据比较多,差不多有50000条,当公司名的树形成后触发ready方法   在ready之后通过_append_json_data方法将子节点依次放置到公司节点下

(先加载公司,数量少,树形成的快,再通过append方法加载大量的子节点,这种append加载速度快并且不会导致页面卡住,下面会比较create_node和_append_json_data的区别)

$('#factoryDeviceTree').on('ready.jstree', function (e, data) {
        // companyCarMap就是后台返回的大量的子节点数据  格式为{key:value,key:value....}
        // key是父节点的id也就是公司Id, value就是这个公司下的所有的子节点数据
        // 子节点数据结构:[{icon: "fa fa-car online", id: "456745898", isBlack: 0, offLineCount: 0,text:"XXXX"},{...},{...},...]
		for(let key in companyCarMap){	
				      $('#factoryDeviceTree').jstree("_append_json_data","#"+key,companyCarMap[key],function(){
					// 这个回调函数要加  不然会报错,即使这个函数里面什么也不做
				});
			}
		}
		
		
   });

    实验发现_append_json_data单次添加子节点的数量在3000秒以内速度都会很快;(红色的框框那条是900个子节点的渲染)

如果单个节点的数量大于3000条 建议放到最后再append,可以参考如下代码:

$('#factoryDeviceTree').on('ready.jstree', function (e, data) {
			
			let lastAddArr = []; // 最后添加的数据
			for(let key in companyCarMap){
				// 如果大于3000  就放到数组中 后一步再append
				if(companyCarMap[key].length>3000){
					lastAddArr.push(key)
				}else{

					$('#factoryDeviceTree').jstree("_append_json_data","#"+key,companyCarMap[key],function(){
						console.log(key,"插入成功",new Date().getTime())
					});
				}
			}
			for (let index = 0; index < lastAddArr.length; index++) {
				const k = lastAddArr[index];
				$('#factoryDeviceTree').jstree("_append_json_data","#"+k,companyCarMap[k],function(){
					console.log(k,"插入成功",new Date().getTime())
				});
			}
			
	});

jsTree加载大量数据的实践就是这些;

 

 

下面是自己为了实现jstree加载大量数据的一步步实践过程:

1、为了加载快速将树形结构和关联的地图分开,第一次加载地图数据和树的数据分开渲染,后面的操作树可以影响地图中的数据,地图和树的数据分开之后优化了1两秒的时间

2、因为树的加载50000条需要30s,并且加载树的时候页面卡顿无法点击,想到有没有先渲染一部分,为展示的部分在慢慢加载拼接进去,于是找到了jsTree中的create_node,但是发现create_node只能一个节点一个节点的添加,性能非常慢,一个一个的数据一次一次的操作DOM ,性能比之前还慢一些。

3、下一步抱着侥幸心理想到了documentFragment,想着创建一个documentFragment,然后jstree直接在文档片段中生成,然后再append到DOM中  希望破灭  jQuery的选择器放documentFragment报找不到该节点

4、希望通过先加载父节点,再在点击的时候请求子节点拼接上去,发现弊端是搜索,搜索走的是前端搜索,有的父节点没点击就没有子节点,搜索数据不全。

5、最后看到了_append_json_data ,抱着试一试的心态,结果不仅防止json之后速度很快,而且他拼接的时候不影响页面,页面一点也不卡顿,_append_json_datacreate_node的区别:create_node是一条一条的添加到DOM中,而_append_json_data是将传递的json数据一次性加载好之后再操作一次dom,有点类似于虚拟DOM感觉。

中间也遇到一些报错,比如调用_append_json_data 的第三个参数一定要传,即使这个回调参数什么也不做,这个是看源码找到的原因。

_append_json_data 源码的位置在1585行 

 

如果有更好的方式或者更深的理解欢迎评论哈~

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值