Dijit 树,如何提高根下有 500 个子节点的大树的性能
Posted
技术标签:
【中文标题】Dijit 树,如何提高根下有 500 个子节点的大树的性能【英文标题】:Dijit tree, how to improve performance for a large tree with 500 child nodes under root 【发布时间】:2011-10-17 09:29:31 【问题描述】:每个树节点都包含其他内部小部件,因此渲染全部 500 个项目需要很长时间,尤其是在 IE 中。
在 IE 中渲染树可能需要 10-20 秒。
我想知道如何改进它,减少渲染时间。
对此有何建议?
我发现有一个TreeGrid,一次只显示一些行,并在用户滚动时更新视图,dijit.Tree有这个功能吗?
【问题讨论】:
【参考方案1】:如果你没有那么多根节点,你可以使用延迟加载机制,例如this article at sitepen
请注意,它适用于 dojo 1.4 - 1.5.1,但在 dojo 1.6.1 中,JsonRestStore 存在一些奇怪的问题。
见this question at ***
编辑以匹配说明
我认为树不可能只在视图区域中构建节点。至少这对于标准 dijit.tree 是不可能的。
在我们的一个应用程序中,我们插入了结构节点作为一种解决方法,即
root
---[1..30] - structure node
---item 1
---item 2
...
---[31..60] - structure node
---item 31
---item 32
...
...
另一方面,听起来树形网格与您想要的非常匹配,也许它可以与一些样式一起使用
【讨论】:
问题是我们有很多同级的子节点。【参考方案2】:这可能是响应迟了,但是我正在做的一个项目也有同样的问题,并且应用程序必须在 IE7 中运行,所以性能肯定不好。核心问题是当您在一个级别上有许多节点时,我们要处理数百甚至一千多个节点,这会导致可怕的脚本运行对话框弹出。
我们最近用我们自己的树实现替换了 dijit.Tree 的使用,发现后备存储的额外抽象是不必要的,因为服务器已经是数据抽象层。因此,我们让服务器生成一个 html 片段,使用 div 和 span 来表示树的结构,并使用自定义属性来关联每个节点的数据。 CSS 用于直观地格式化数据。
这种方法利用浏览器的内在能力来处理 HTML。与鼠标和键盘事件的一些连接使我们能够以有效的方式获得完整的基于树的功能(包括节点的工具提示)。下面是我们服务器生成的 HTML 结构类型的简化示例:
<div class="treeFolder">
<span class="treeFolderInd">+</span>
<span class="treeFolderLabel">Folder label</span>
<div class="treeFolderContent">
<div class="treeFolder">
<span class="treeFolderInd">+</span>
<span class="treeFolderLabel">Sub-folder</span>
<div class="treeFolderContent">
<div class="treeItem" my-action="doSomething"
my-data="arg1:'hello', arg2:'world'"
my-tooltip="Goodbye">
<span class="treeItemInd">o</span>
<span class="treeItemContent">
Item text
</span>
</div>
<div class="treeItem" my-action="doSomethingElse"
my-data="arg1:'foo', arg2:'bar'"
my-tooltip="Another tip">
<span class="treeItemInd">o</span>
<span class="treeItemContent">
Item text
</span>
</div>
...
类名用于 CSS 格式化。各种 my-* 属性是应用程序客户端用来将操作与用户选择树节点时相关联的自定义属性。我们在数据中使用JSON字符串来表示,所以可以在属性上使用dojo.fromJson()来获取与节点关联的数据(我们内部缓存了用DOM节点创建的对象,所以fromJson()不必每次访问数据时使用。
我们的加载时间已大大缩短,现在浏览器本身是解析 HTML 花费最多时间的浏览器,但它并不比加载大型网页更糟糕。一旦加载了 HTML 数据并且我们注册了我们的事件钩子,扩展一个包含 5,000 个项目的节点是相当快的。我们基本上只是将 CSS 显示设置切换为展开/折叠文件夹,因此您基本上受限于浏览器本身的执行方式。
当然,可以创建替代结构来表示树数据,但我想你明白了。我们将树的核心功能封装在一个类中,其中包含一些虚拟事件来表示何时单击项目和其他树动作。该类的用户只需使用 dojo.connect() 连接到感兴趣的树事件。
旁注:为所有项目创建 dijit.Tooltip 实例是降低性能的一个重要因素。为了解决这个问题,我们通过直接使用 dijit.showTooltip() 和 dijit.hideTooltip() 来管理自己的工具提示渲染,而不是创建 dijit.Tooltip 实例。
对我们来说不幸的事情是卡在 IE7 中。 IE7 在处理大型数据集时会降低整体性能,即使系统有足够的 RAM。 IE8和IE9在这方面有很大的改进。
【讨论】:
【参考方案3】:您可以尝试将Lazy Tree Grid 与查询读取存储一起使用。这可以满足您的需要。在急切加载父母之后延迟加载孩子。还可以控制需要加载的父元素个数,grid.rowsPerPage
【讨论】:
从历史上看,问题在于给定级别的节点数量。因此,即使使用延迟加载,如果对于给定的级别,您有数百到数千个节点,您仍然会遇到问题。以上是关于Dijit 树,如何提高根下有 500 个子节点的大树的性能的主要内容,如果未能解决你的问题,请参考以下文章