列表加载优化方案.md 4.0 KB

借用列表加载速度优化方案

一、问题分析

列表加载慢可能来自以下方面:

来源 可能原因
后端 API 数据库查询慢、N+1 查询、缺少索引、返回字段过多
前端请求 首次加载时并发请求多、请求参数冗余
前端渲染 列过多、复杂 formatter/cellRender、compute 计算量大

二、后端优化(需后端配合)

2.1 数据库层面

  • 索引:为常用筛选字段建索引(如 statuscreate_datetimeborrow_type
  • 分页:确保使用 limit/offset 或游标分页,避免全表扫描

2.2 接口层面(Django 示例)

# 使用 select_related / prefetch_related 减少 N+1 查询
queryset = BorrowApplication.objects.select_related(
    'borrower_info', 'creator'
).prefetch_related(
    'items'
).only('id', 'application_no', 'status', ...)  # 只返回列表需要的字段

2.3 返回字段精简

  • 列表接口只返回表格展示所需字段
  • 详情接口再返回完整数据

三、前端优化(可立即实施)

3.1 移除调试日志

crud.tsxpageRequestconsole.log(query) 会在每次请求时执行,生产环境应移除。

3.2 减少首屏列数

  • 将非核心列默认 show: false,通过列设置由用户按需显示
  • 当前已有部分列隐藏,可继续评估是否可再精简

3.3 优化 formatter

  • dayjs 等格式化逻辑尽量复用,避免每行重复创建
  • 简单格式化可考虑后端直接返回格式化字符串

3.4 延迟加载弹窗组件

  • 使用 defineAsyncComponent 或路由懒加载,减少首屏 bundle
  • 弹窗在首次打开时再加载对应组件

3.5 请求参数优化

  • 确保 transformQuery 只传递有值的搜索条件,减少无效参数

3.6 避免重复刷新

  • handleBorrowSubmit 中已去除重复的 doRefresh 调用,仅保留 crudExpose.doRefresh()

3.7 首屏加载与 doSearch

  • 若通过 URL 的 status 做初始筛选,onMounted 中会调用 doSearch。若 fast-crud 默认也会做一次初始请求,可能造成首屏请求两次,可考虑在 crud 配置中关闭默认首次加载,仅依赖 doSearch 触发

四、排查步骤

  1. 定位瓶颈:用浏览器 DevTools → Network 查看 /api/system/borrow/application/ 请求耗时

    • 若接口耗时 > 1s,重点优化后端
    • 若接口很快但页面渲染慢,重点优化前端
  2. 后端慢:检查数据库慢查询、接口是否有 N+1、是否缺少索引

  3. 前端慢:检查列数量、formatter 复杂度、是否有大量 compute


五、列表缓存(已实现)

5.1 实现方式

  • 工具src/utils/requestCache.ts 提供通用 createRequestCache
  • 接入crud.tsxpageRequest 使用缓存,相同查询参数在 TTL 内直接返回缓存
  • 失效:增删改、领取、归还等操作后调用 invalidateBorrowListCache()doRefresh(),确保展示最新数据

5.2 配置

  • TTL:默认 30 秒,可在 crud.tsx 中调整 createRequestCache({ ttl: 30 * 1000 })
  • keyPrefixborrow:list:,用于按业务隔离

5.3 适用场景

  • 分页来回切换(如 1→2→1)时,相同页可立即展示
  • 短时间内重复搜索相同条件时,减少后端请求

5.4 其他列表复用

其他 crud 列表如需缓存,可参考借用列表:

import { createRequestCache } from '/@/utils/requestCache';
const cache = createRequestCache({ ttl: 30 * 1000, keyPrefix: 'xxx:list:' });
// pageRequest 中:先 cache.get(query),命中则返回;否则请求后 cache.set(query, res)
// 变更后:export invalidateXxxListCache,在刷新前调用

六、快速见效项(优先级)

  1. 移除 console.log(立即)
  2. 后端:为 statuscreate_datetime 等建索引
  3. 后端:列表接口使用 select_related/prefetch_related 并精简返回字段
  4. 前端:确认 pageSize 合理(当前 10 条/页已较小)