前言
公司erp系统采用Jeecg开源框架,前端:JeecgBoot-Vue3,后端:JeecgBoot
问题
在JeecgBoot-Vue3中,基于Ant Design Vue
封装的table 组件 BasicTable
,用于展示列表数据。
列表分页时,每页条数(pageSize)数值大时(如数值为200),点击查询按钮查询,反应迟钝,且数值越大,反应时间越长(分页参数相同时,反应时间与后端接口有关,此处不讨论数据库表设计问题:对于查询逻辑复杂一点,联表查询稍微多一点的接口,反应超级明显)。
第一步排查:接口请求以及响应时间
图一:第一次进入列表页面,请求接口,查询列表数据,浏览器F12 waterfall性能检测如下
图二:即图一数据加载后,立即点击"查询"按钮,请求接口,查询列表数据,页面无任何反应(数秒甚至一两分钟)
图三:即图二后,页面无任何反应,一段时间后,开始加载数据
图四:即图三后,请求接口,查询列表数据,浏览器F12 waterfall性能检测如下
第二步排查:代码排查
每页200条数据,点击"查询"按钮,数秒后才开始调用接口。因此,排查分页参数传值处代码,如下所示:
src\components\Table\src\hooks\useDataSource中fetch方法
第三步排查:验证问题
通过控制台打印代码运行时间,直观感受问题所在
-
每页展示200 条数据时,控制台打印如下:
-
每页展示500 条数据时,控制台打印如下:
经过多次排查,发现是合并分页参数时,使用对象展开运算符(...)导致操作速度慢
解决方案
使用Object.assign()方法代替对象展开运算符(...)来复制对象
js
// 解决合并分页对象性能差问题(分页时,每条页数数值大时,点击查询按钮,反应迟钝。数值越大,反应时间越长)
const copyParams = Object.assign({}, pageParams);
let params: Recordable = {
copyParams,
// 由于 getFieldsValue 返回的不是逗号分割的数据,所以改用 validate
...(useSearchForm ? await validate() : {}),
...searchInfo,
...defSort,
...(opt?.searchInfo ?? {}),
...sortInfo,
...filterInfo,
...(opt?.sortInfo ?? {}),
...(opt?.filterInfo ?? {}),
};
if (beforeFetch && isFunction(beforeFetch)) {
params = (await beforeFetch(params)) || params;
}
const res = await api(params);
rawDataSourceRef.value = res;
- 每页展示2000 条数据时,控制台打印如下: