阿里云飞天发布时刻,领先大模型限免,超7000万 tokens免费体验 了解详情
写点什么

前端 tree 优化实践:渲染速度从 14.65s 到 0.49s

  • 2019-02-15
  • 本文字数:2072 字

    阅读完需:约 7 分钟

前端tree优化实践:渲染速度从14.65s到0.49s

全篇主要思想:递归的本质是栈的读取

先看效果对比

以下都是基于 10000 条子节点数据作对比,先上最终数据对比:


递归版 tree,渲染速度: 14.65s,点击节点处理速度: 9.83s


优化版 tree,渲染速度: 0.49s,点击节点处理速度: 0.18s


递归组件实现 tree:渲染速度 15.71s -1.06s = 14.65s



递归版 tree 性能图-1


递归组件版 tree 点击节点性能分析图:点击节点处理速度: 10.19s - 0.357s = 9.833s ≈ 9.83s



递归 tree 点击节点图-2


最终优化实现 tree: 渲染速度 2.25s - 1.76s = 0.49s



优化 tree 性能图-3


优化版 tree 点击节点性能分析图:点击节点处理速度 0.623s - 0.3s = 0.3s



优化 tree 点击节点图-4


最终对比是:


递归版 tree,渲染速度: 12.19s,点击节点处理速度: 9.52s


优化版 tree,渲染速度: 0.49s,点击节点处理速度: 0.18s

分析问题

我们可以借助 performance 分析一下递归组件的耗时点所在,上递归组件渲染的性能分析:

1.script 耗时分析:


递归 tree script 性能分析图-5


通过图-1 性能瀑布可以清晰的看到 script 执行占了 8.9s 的时间,通过上图即图-5 可以看到 script 的的调用栈主要集中在创建 vue 实例时的 createChildren 上面。

2.render 耗时分析


递归 tree render 性能分析图-6


通过上图即图-6 可以清晰的看到 render 耗时主要集中在 Recalculate Style、Layout 上面。我们知道 Recalculate Style、Layout 主要是样式计算,因此查看代码:



递归组件部分代码图-7


发现在递归的 tree-node 组件里面有很多样式的计算,10000 条子节点就需要计算 10000 次。

3.DOM 结构分析


递归组件 DOM 结构图-8

实现思想

来看我们的开篇思想:递归的本质是栈的读取。


在算法中我们会遇到很多递归实现的案例,所有的递归都可以转换成非递归实现,其中转换的本质是:递归是解析器(引擎)来帮我们做了栈的存取,非递归是手动创建栈来模拟栈的存取过程。


万物都是相通的,递归组件也可以转换成扁平数组来实现:


1.更改 DOM 结构成平级结构,点击节点以及节点的视觉样式通过操作总的 list 数据去实现


2.然后使用虚拟长列表来控制 vue 子组件实例创建的数量。

优化版实现

主要分为两部分功能:


1.tree 数据和 DOM 结构的扁平化;


2.虚拟长列表控制 DOM 渲染数量。

1.tree 数据和 DOM 结构的扁平化


优化版 tree 的 DOM 结构图-9


由上图我们可以看到经过改造之后的 tree 的 DOM 结构,父节点和子节点是平级的,在操作子节点时去操作内存中的 listData 数据来改变相关联节点的状态。


我们再看下 listData 数据的结构:



优化版 tree listData 数据结构图-10


上图即图-10 结合图-9 的 DOM 结构可以对整个功能的实现逻辑一目了然:


listData 中的每一项的 style、checked、path 等信息来描述节点的样式位置和状态,操作一个节点时通过 listData 更改相关节点的状态样式等信息。


因此最终来写我们的代码:



实现.vue 代码图-11


我们再看下 handleCheckChange 的做了什么:



handleCheckChange 处理逻辑图-12

2.虚拟长列表控制 DOM 渲染数量

实现思路:


根节点 DOM 分成两个子节点:fui-tree__phantom 和 fui-tree__content。


两个子节点都是绝对定位,为了在滚动时避免数据的更改回头触发滚动事件。



虚拟列表 DOM 组织结构图-13


根节点解两个子节点 css:


.fui-tree {    height: 400px;    overflow: auto;    position: relative;  }
.fui-tree__phantom { position: absolute; left: 0; top: 0; right: 0; z-index: -1; }
.fui-tree__content { left: 0; right: 0; top: 0; position: absolute; }
复制代码


然后我们通过滚动条的位置来计算我们应该要取哪些数据。


主要代码:



通过 startIndex、endIndex 可以取出我们需要循环的数据列表 renderNodes:


computed: {      renderNodes() {        if (!this.treeNode) return []        return this.treeNode.listData.slice(this.positionConfig.startIndex, this.positionConfig.endIndex)      },      phantomStyle() {        return {          height: this.allListLen * 20 + 'px'        }      }    }
复制代码


结合图-11 的 v-for,这样我们在渲染时的 dom 数量是固定的条数,如下图:



优化版 tree DOM 数量是固定的图-15


虚拟列表的接入可以让即使再多数据量也能渲染固定的 DOM 数量,这样就可以支撑更大数据的渲染和功能。


以上我们实现了业务需求的大数据渲染,目前测试可支撑到 20w 条节点,点击子节点时会有肉眼可见的延迟,主要是图-12 中 handleCheckChange 的数据查找和处理,这块还有一定的优化空间:使用字典树存储节点相关信息,字典树和扁平数组 listData 的每一个元素指向同一个内存地址,在 handleCheckChange 中通过操作字典树来达到操作 listData 的元素的效果,经典的空间换时间的案例。

参考链接


更多内容,请关注前端之巅。



会议推荐


2019 年 6 月,GMTC 全球大前端技术大会 2019 即将到来。小程序、Flutter、移动 AI、工程化、性能优化…大前端的下一站在哪里?点击下图了解更多详情。



2019-02-15 10:228264

评论

发布
暂无评论
发现更多内容

数据标注,优化模型辅助标注、Label 库管理|ModelWhale 版本更新

ModelWhale

云计算 编程 模型 数据标注 数据门户

ZincSearch 一款 Elasticsearch 的轻量级替代品

宇宙之一粟

Go 三周年连更 ZincSearch

和ChatGPT结对完成VS CODE插件项目分享

马说IT

vscode 插件 插件开发 ChatGPT

什么是 ChatGPT Plus,您应该得到它吗?

外贸IT程序客

ChatGPT 人工智能ChatGPT 吗? ChatGPT4

软件测试/测试开发丨面试题之Linux 与 Python 编程篇

测试人

软件测试 面试题 测试开发

Apache Doris 1.2.4 Release 版本正式发布|版本通告

SelectDB

数据库 大数据 数据分析 Doris 联邦查询和分析

Go 语言中没有枚举类型,但是我们可以这样做

陈明勇

Go golang 枚举 Enum 三周年连更

如何修复 ChatGPT 的内部服务器错误消息

外贸IT程序客

ChatGPT 人工智能ChatGPT 吗? ChatGPT4

ChatGPT 应用汇总及操作手册

外贸IT程序客

ChatGPT 人工智能ChatGPT 吗? ChatGPT4

这8个摸鱼神器,千万别让你老板知道!

引迈信息

效率 程序员 工具 低代码 JNPF

副业做得好,搞钱没烦恼:盘点那些靠谱的程序员副业!

禅道项目管理

程序员 副业 技术博客

性能大PK count(*)、count(1)和count(列)

架构精进之路

MySQL 数据库 后端 innodb 三周年连更

【源码分析】【seata】at 模式分布式事务 -xid隐式传递

如果晴天

源码分析 分布式事务 seata spring-cloud Seata框架

ChatGPT 有字符限制吗?这是绕过它的方法

外贸IT程序客

ChatGPT 人工智能ChatGPT 吗? ChatGPT4

轻量级协作任务管理看板

顿顿顿

敏捷开发 任务管理 敏捷开发管理工具 看板工具 scrum工具

人工智能训练数据集:误区、挑战与应对方法

数据堂

iOS MachineLearning 系列(8)—— 图片热区分析

珲少

中国厨房更净一步:一场科技“下凡”带来的方太式浪漫

脑极体

场景篇-ChatGPT帮我实现发送公众号推文

马说IT

微信公众号 代码生成 ChatGPT

iOS MachineLearning 系列(7)—— 图片相似度分析

珲少

指导机器人如何翻译狗叫笑话

FinClip

12秒内AI在手机上完成作画!谷歌提出扩散模型推理加速新方法

Openlab_cosmoplat

人工智能 机器学习 AI绘画

eBPF的发展演进---从石器时代到成为神(四)

统信软件

操作系统 Linux Kenel

龙蜥开发者说:亲历从基础设施构建到系统质量保障,龙蜥未来可期 | 第 19 期

OpenAnolis小助手

Linux 开源 sig 龙蜥开发者说 联通数科

场景篇-ChatGPT帮我搭建博客网站并自动写博客!

马说IT

博客 ChatGPT

什么是 GPT-4,它是如何工作的?ChatGPT 的新模型解释

外贸IT程序客

ChatGPT 人工智能ChatGPT 吗? ChatGPT4

会思考的狗、聪明的马和随机鹦鹉

FinClip

ChatGPT 在 Python WEB 的Prompt项目分享

马说IT

Python 开发 ChatGPT

极客星球|数据分析引擎黑马ClickHouse技术研究与实践

MobTech袤博科技

小程序化数字人:构建智能化的门户解决方案

FinClip

前端tree优化实践:渲染速度从14.65s到0.49s_大前端_杨涛峰_InfoQ精选文章