目录
前言
在当今数字化时代,数据量呈爆炸式增长,企业与组织面临着海量数据的管理和展示需求。对于基于 Ruoyi 框架开发的系统而言,TreeTable 作为一种常见的数据展示组件,能够以树形结构清晰地呈现层级关系数据,广泛应用于各类管理系统中。然而,当面对大规模数据加载时,TreeTable 的性能瓶颈逐渐凸显,严重影响用户体验与系统运行效率。本文将深入探讨针对大规模数据加载的 Ruoyi TreeTable 优化方案,并以 POI(Point of Interest,兴趣点)分类集中管理为例,详细阐述优化的必要性、面临的挑战以及具体的优化策略,旨在为相关开发人员提供实践参考,助力提升系统性能与数据处理能力。
针对大规模数据加载的 Ruoyi TreeTable 优化具有重要的现实意义与紧迫性。通过对 POI 分类集中管理这一典型场景的优化实践,我们将深入剖析优化过程中的关键技术和策略,并总结经验教训,为其他类似场景提供可借鉴的优化思路。在接下来的章节中,我们将详细阐述优化的具体实施步骤与效果评估,以期为 Ruoyi 框架开发者及相关领域的从业者提供有价值的参考,共同推动系统性能的提升与用户体验的优化。
一、Ruoyi原生TreeTable性能瓶颈
在实际业务场景中,POI 分类集中管理是许多地理信息系统(GIS)和位置服务相关应用的核心功能。例如,城市规划部门需要对各类兴趣点(如商业中心、学校、医院等)进行分类管理,以便更好地进行资源配置与规划;旅游服务平台则需要高效地展示不同地区的景点信息,方便用户查询与规划行程。这些场景中,POI 数据量庞大且层级关系复杂,TreeTable 承载着将这些数据以清晰、高效的方式呈现给用户的重要任务。然而,传统的 TreeTable 加载方式在处理大规模数据时,往往会出现加载缓慢、页面卡顿甚至崩溃等问题。一方面,前端一次性加载大量数据会导致浏览器内存占用过高,渲染速度变慢;另一方面,后端在处理大规模数据查询与传输时也会面临性能瓶颈,影响整体响应速度。优化 Ruoyi TreeTable 的大规模数据加载性能,不仅能够提升用户操作体验,减少等待时间,还能提高系统的稳定性和可靠性,避免因数据加载问题导致的系统故障。同时,通过优化数据加载方式,可以降低系统资源消耗,提高资源利用率,为企业节省运营成本。此外,优化后的 TreeTable 将能够更好地适应未来数据量的持续增长,为系统的可持续发展奠定基础。本节将重点从原始的解决方案来加载时可能会遇到什么问题,同时简单介绍官网遗留的一些历史issue,让大家对这些问题有一个基本的认识和了解。
1、展示需求
其实最开始我们直接使用若依的TreeTable的方式来对不同的POI类型进行展示管理。在开始的时候,由于其数据量不大,对性能的要求也不高,在数据的展示需求下还能初步符合的。最早期的界面展示如下:
我们采用的是类似于菜单的形式,基本也是符合的。但是在实际展示过程中,当我们新增了百度的POI分类管理之后就会发现其界面加载速度很慢,使用以下sql查询数据,
select * from biz_poi_category;
在数据库中大约有3038条记录,当然这3038条记录不是所有都是平级的,而是有多层次的关联。因此在展示的时候需要对这些数据进行循环展示,由此就导致了渲染的速度非常慢。3038条数据在我本地的开发机器上展示的时间几乎花了3分钟的时间,而且每次新增或者编辑了POI分类之后都非常慢,进而影响我们对POI的分类管理功能。 那么如何来解决这个问题呢?
2、官方Issue
带着这个问题,我来Ruoyi的官方源代码地址,看看有没有其它的小伙伴曾经遇到过这个问题,在面对大规模的数据展示的时候碰到这个问题。如果官方有比较好的解决方案,那么我们可以直接采用,这样就比较方便。在其Issue中查找时,还真的就发现了一些关于TreeTable的展示的线索,如下所示:
这是一条在2020年3月17日发表的Issue,也是遇到了TreeTable的大数据量展示的问题,在这个问题中,作者给我们提供了一条解决办法,参考ztree来实现,将ztree和table来进行组合实现。因此我们根据开源作者的思路来进行性能瓶颈的突破和实现。
二、解决性能瓶颈问题
本节将重点介绍性能提升的解决思路以及具体落地的前后端设计与实现。通过本节的内容讲解,大家对如何在Ruoyi中解决性能瓶颈问题有一个较好的掌握。
1、解决思路
在优化过程中,我们需要综合考虑前端与后端的协同优化策略。前端方面,可以采用虚拟滚动技术,仅加载可视区域内的数据,减少不必要的数据渲染;同时,对 TreeTable 的数据结构进行优化,减少层级嵌套深度,提高渲染效率。后端则需要优化数据库查询语句,采用分页查询、缓存机制等技术手段,减少单次查询的数据量,加快数据传输速度。此外,还可以通过引入异步加载机制,实现数据的按需加载,进一步提升系统的响应速度。以 POI 分类集中管理为例,优化后的 Ruoyi TreeTable 将能够快速响应用户的查询请求,高效地展示不同层级的 POI 数据,无论是城市级别的宏观展示还是具体区域的详细查看,都能为用户提供流畅、便捷的操作体验。这不仅有助于提高工作效率,还能增强用户对系统的满意度与信任度。
2、后端设计与实现
与用户的功能展示相同,将treeTable改为左边使用Ztree,右边使用table的形式展示后,我们后端的接口和方法也需要进行相应的调整。本小节将重点介绍后端java程序部分的设计与实现。后端改造的成本还是比较低的,原来的后端树形接收方法如下:
@RequiresPermissions("poisubject:poi:list")
@PostMapping("/list")
@ResponseBody
public List<PoiCategory> list(PoiCategory category)
{
List<PoiCategory> categoryList = poiCategoryService.selectPoiCategoryList(category);
return categoryList;
}
可以看到这里是一次性的将真个POI分类列表返回给前后,由前来来进行树形的构建,因此主要导致显示慢的原因就是前端的页面渲染上,那么如何提高整个POI分类列表的渲染效率呢?后端可以做什么工作呢?我们需要将方法调整为,只查询当前分类的直属节点,其更下级节点暂不展示,这样就能避免更多的子集查询,改造后的方法如下:
/*
* list 要改成支持分页的查询方法
*
*/
@RequiresPermissions("poisubject:poi:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(PoiCategory category)
{
startPage();
List<PoiCategory> list = poiCategoryService.selectPoiCategoryList(category);
return getDataTable(list);
}
这样后端的程序改造基本就完成,需要改动的就是将数据的查询方式从List全部返回改成TableDataInfo返回分页的实体信息。 下面再来讲一下如何对前端来进行改造。
3、前端设计与实现
相比之下,前端的升级改造工作更加繁忙,这里需要新增一个左边的Ztree树,html页面的展示元素如下:
<div class="box box-main">
<div class="box-header">
<div class="box-title">
<i class="fa icon-grid"></i> POI分类
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" id="btnExpand" title="展开" style="display:none;"><i class="fa fa-chevron-up"></i></button>
<button type="button" class="btn btn-box-tool" id="btnCollapse" title="折叠"><i class="fa fa-chevron-down"></i></button>
<button type="button" class="btn btn-box-tool" id="btnRefresh" title="刷新分类"><i class="fa fa-refresh"></i></button>
</div>
</div>
<div class="ui-layout-content">
<div id="tree" class="ztree"></div>
</div>
</div>
然后需要定义Ztree的数据加载方式,核心的数据加载程序如下所示:
function queryPoiTree(){
var url = ctx + "/poisubject/poi/poicategory/treeData";
var options = {
url: url,
expandLevel: 2,
onClick : zOnClick
};
$.tree.init(options);
function zOnClick(event, treeId, treeNode) {
$("#parentId").val(treeNode.id);
$.table.search();
}
}
这里需要说明以下,这里展示ztree的数据treeData接口在之前的程序管理代码中也是可以使用的,因此在这里可以实现复用。除此之外,在界面操作过程中,点击了页面的左边的树形节点,右边的表格对象需要同步进行刷新,这就需要使用这里的检索方法,同时在表格的定义那创建查询的方法,核心方法如下所示:
function queryPoiList() {
var options = {
url: prefix + "/list",
createUrl: prefix + "/add/{id}",//这里一定要加{id},否则会报get方法不支持的bug
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove/{id}",
//exportUrl: prefix + "/export",
sortName: "orderNum",
sortOrder: "asc",
modalName: "POI分类",
columns: [{
checkbox: true
},
{
field: 'pkId',
title: '',
visible: false
},
{
field: 'categoryName',
title: '分类名称',
align: "left"
},{
field: 'originCode',
title: '原始编码',
align: "left"
},
{
field: 'platform',
title: '来源平台',
align: "left",
formatter: function(value, item, index) {
return $.table.selectDictLabel(platformDatas, item.platform);
}
},
{
field: 'orderNum',
title: '排序',
align: "left"
},
{
field: 'status',
title: '状态',
align: "left",
formatter: function(value, item, index) {
return $.table.selectDictLabel(datas, item.status);
}
},
{
field: 'createTime',
title: '创建时间',
align: "left"
},
{
title: '操作',
align: 'left',
formatter: function(value, row, index) {
if (row.parentId != 0) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.pkId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-info btn-xs ' + addFlag + '" href="javascript:void(0)" onclick="$.operate.add(\'' + row.pkId + '\')"><i class="fa fa-plus"></i>新增</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.pkId + '\')"><i class="fa fa-trash"></i>删除</a>');
return actions.join('');
} else {
return "";
}
}
}]
};
$.table.init(options);
}
在这个方法中一定要注意一个点,就是add方法的处理地址,一定要在连接后面加上{id},否则程勋运行过程中就会一直报错, 从而导致我们不能正常的使用功能。经过以上的编码以及前后端的设计与实现,我们基本就完成了ztree在左而表格在右的一个程序展示,下一步我们将对系统操作进行展示。
三、成果展示
本节将基于前面两节的成果,对完成的功能进行展示,分别从列表界面和性能展示两个方面来进行。
1、列表展示
经过之前的工作和开发设计,我们基本就实现了界面的调整,左边的ztree树形展示,右边的左表展示,点击树形组件的具体节点,右边可以查询当前节点的直属子节点,这样会比较容易管理。这样从功能上就比较容易进行数据查询和检索。
2、性能展示
除了功能上满足我们对不同平台的POI分类进行统一的管理,同时还能有效的提高速度,这里我们以本地开发环境的浏览器调试工具进行调整。可以看到数据查询的速度比较快,基本没有出现什么卡顿的情况。到此问题基本得到了比较好的解决。
四、总结
以上就是本文的主要内容,本文将深入探讨针对大规模数据加载的 Ruoyi TreeTable 优化方案,并以 POI(Point of Interest,兴趣点)分类集中管理为例,详细阐述优化的必要性、面临的挑战以及具体的优化策略,旨在为相关开发人员提供实践参考,助力提升系统性能与数据处理能力。 针对大规模数据加载的 Ruoyi TreeTable 优化具有重要的现实意义与紧迫性。通过对 POI 分类集中管理这一典型场景的优化实践,我们将深入剖析优化过程中的关键技术和策略,并总结经验教训,为其他类似场景提供可借鉴的优化思路。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。