当前位置: 首页 > java >正文

树结构无感更新及地图大批量点位上图Ui卡顿优化

树结构无感更新及地图大批量点位上图Ui卡顿优化

一、树结构无感更新

在实际的项目应用中,有时候需要定时更新树结构。但是要避免影响用户的使用,这时候如何做到无感更新呢?

1、此处以统计数量的树结构为例,无感更新数量

高性能版本:一次建表,快速更新

具体的实现代码如下所示

/*** 构建节点 Map,id -> 节点引用*/
function buildNodeMap(tree, map = new Map()) {for (const node of tree) {map.set(node.id, node);if (node.children) {buildNodeMap(node.children, map);}}return map;
}
/*** 用新树的 count 更新旧树*/
function updateCountsByMap(oldTreeMap, newTree) {for (const node of newTree) {const oldNode = oldTreeMap.get(node.id);if (oldNode) {oldNode.count = node.count; // 更新数量if (node.children) {updateCountsByMap(oldTreeMap, node.children); // 递归同步}}}
}
// ======================
// 示例
// ======================
// 旧树(带 checked)
let oldTree = [{ id: 1, name: 'A', count: 5, checked: true, children: [{ id: 2, name: 'A1', count: 2, checked: false },{ id: 3, name: 'A2', count: 4, checked: true }] }
];
// 新树(最新 count)
let newTree = [{ id: 1, name: 'A', count: 7, children: [{ id: 2, name: 'A1', count: 3 },{ id: 3, name: 'A2', count: 6 }] }
];
// 先构建旧树的 Map(只做一次)
const oldTreeMap = buildNodeMap(oldTree);
// 定时更新
setInterval(() => {// 模拟接口返回const latestTree = JSON.parse(JSON.stringify(newTree));// 快速更新旧树的数量updateCountsByMap(oldTreeMap, latestTree);console.log("旧树已更新:", JSON.stringify(oldTree, null, 2));
}, 5000);

2、此更新优点

  • 1、O(n) 更新速度
    因为每个节点查找是 O(1)(Map),所以总时间复杂度是节点数量的线性。

  • 2、大树高频更新不卡
    即使 10 万节点,每次更新也能在几十毫秒内完成。

  • 3、引用不变
    旧树引用保持不变(适合 Vue / React),不会引起整棵树重渲染,只会局部响应。

  • 4、保留所有状态
    checked、expanded 等 UI 状态不受影响。

二、地图大批量点位上图UI卡顿优化

1、涉及大量计算导致UI卡顿

使用Worker 多线程解析数据,这样可以减少主线程的压力。避免造成UI卡顿,用户体验不好

2、点位数量大导致UI卡顿

解决思路主要有以下几点:

  • 视野内渲染(Spatial Filter)
    大多数时候用户只看得到当前地图窗口里的点,视野外的点可以不画

  • 聚合(ClusterLayer

  • work + 分帧渲染

work + 分帧渲染 简单实例代码如下:

const worker = new Worker('worker.js');
const layer = new maptalks.VectorLayer('layer').addTo(map);
worker.onmessage = e => {const points = e.data;const batchSize = 500; // 每帧加载数量let index = 0;function addBatch() {const batch = points.slice(index, index + batchSize).map(p => new maptalks.Marker([p.lng, p.lat], {symbol: {markerType: 'ellipse',markerFill: p.color,markerWidth: 8,markerHeight: 8}}));layer.addGeometry(batch);index += batchSize;if (index < points.length) {requestAnimationFrame(addBatch);}}requestAnimationFrame(addBatch);
};
// 启动
worker.postMessage({ points: allPoints });

🔹 为什么这样能避免卡顿

  • 数据准备在 Worker → 主线程完全不卡

  • 渲染分批 → 每一帧加少量点,保证渲染时间 < 16ms,不阻塞 UI

  • 体验效果 → 用户可以先看到部分点,地图可以流畅缩放/拖拽,剩余点在后台慢慢加

http://www.xdnf.cn/news/17738.html

相关文章:

  • Spring AI Alibaba - 聊天机器人快速上手
  • 机器学习——DBSCAN
  • 读《精益数据分析》:UGC平台的数据指标梳理
  • Go面试题及详细答案120题(0-20)
  • 【工具】通用文档转换器 推荐 Markdown 转为 Word 或者 Pdf格式 可以批量或者通过代码调用
  • 【前端:Html】--3.进阶:图形
  • c#联合Halcon进行OCR字符识别(含halcon-25.05 百度网盘)
  • 解决H616用网络的IP地址连不上
  • 考研复习-计算机组成原理-第五章-CPU
  • MySQL User表入门教程
  • 计算机视觉(7)-纯视觉方案实现端到端轨迹规划(思路梳理)
  • 从爬虫新手到DrissionPage实践者的技术旅程
  • MCU中的液晶显示屏LCD(Liquid Crystal Display)控制器
  • Unity UnityWebRequest常用操作
  • 使用pyqt5实现可勾选的测试用例界面
  • 99、【OS】【Nuttx】【构建】cmake 配置实操:问题解决
  • 【模型剪枝2】不同剪枝方法实现对 yolov5n 剪枝测试及对比
  • Linux,docker知识补充
  • 自建知识库,向量数据库 体系建设(二)之BERT 与.NET 8
  • C++少儿编程(二十二)—条件结构
  • 通过限制对象的内存分配位置来实现特定的设计目标
  • powerbi本地报表发布到web,以得到分享链接
  • Day13 Vue工程化
  • SQL 语言分类
  • 人大BABEC地平线高效率具身导航!Aux-Think:探索视觉语言导航中数据高效的推理策略
  • @RequestMapping接收文件格式的形参(方法参数)
  • idea git commit特别慢,cpu100%
  • 13.深度学习——Minst手写数字识别
  • 嵌入式第二十六天(文件IO相关操作)
  • 基于PROFINET的西门子PLC通讯:S7-200与S7-1200在自动化仓储中的协同应用