10000条数据,浏览器卡死3秒?这招让它0.01秒搞定!
你有没有这样的经历?
页面 loading 转圈圈,点了没反应,过了几秒浏览器弹出"页面无响应"...
罪魁祸首可能就是一个简单的树形结构转换!
今天分享一个实战案例,教你从 O(n²) 优化到 O(n) ,性能提升 210倍!
🔥 问题场景
后端返回扁平数据,前端要转成树形结构展示:

❌ 错误写法:递归遍历
javascript
// 时间复杂度 O(n²) - 数据量大直接卡死
function buildTree(data, parentId = 0) {
const result = []
data.forEach(item => {
if (item.parentId === parentId) {
const node = { ...item }
node.children = buildTree(data, item.id) // 递归,每次都遍历全数组
result.push(node)
}
})
return result
}
问题: 找每个节点的子节点都要遍历一遍数组,10000条数据要循环 1亿次!
✅ 正确写法:Map映射
javascript
// 时间复杂度 O(n) - 只需遍历2次
function buildTree(data) {
const map = new Map()
const tree = []
// 第1遍:建立 id → node 映射
data.forEach(item => {
map.set(item.id, { ...item, children: [] })
})
// 第2遍:挂到父节点下
data.forEach(item => {
const node = map.get(item.id)
if (item.parentId === 0) {
tree.push(node) // 根节点
} else {
map.get(item.parentId)?.children.push(node)
}
})
return tree
}
核心优化: 用 Map 做索引,查找从 O(n) 变成 O(1)!
📊 实测对比
常规性能测试结果:数据越大,加速比越大。
| 1000条数据 | 3000条数据 |
|---|---|
![]() |
![]() |
webWorker性能测试结果:在webWorker下,常规递归方法也变得很快,且解决了页面"假死"情况出现。
| 1000条数据 | 10000条数据 |
|---|---|
![]() |
![]() |
🚀 终极方案:Web Worker
数据量超大时,用 Web Worker 避免阻塞主线程:
javascript
// 主线程
const worker = new Worker('./tree.worker.js')
worker.postMessage({ data: rawData })
worker.onmessage = (e) => {
treeData.value = e.data.result
worker.terminate() // 用完销毁
}
效果: loading 动画流畅,页面完全不卡!
💡 一句话总结




