Dijit树,如何提高根下有500个子节点的大树的性能

发布于 2024-12-10 11:05:23 字数 193 浏览 0 评论 0原文

每个树节点都包含其他内部小部件,因此渲染整个 500 个项目需要很长时间,尤其是在 IE 中。

在 IE 中渲染树可能需要 10-20 秒。

我想知道如何改进它,减少渲染时间。

对此有什么建议吗?

我发现有一个 TreeGrid,一次只显示一些行,并在用户滚动时更新视图,dijit.Tree 有这个功能吗?

Each tree node contains other inner widgets, so it takes long time to render the whole 500 items especially in IE.

It may take 10-20 seconds to render the tree in IE.

I was wondering how to improve it, reduce the render time.

Any suggestion on this?

I found there is a TreeGrid, only show some rows at a time, and update the view while user scroll, does dijit.Tree have this capability?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

走走停停 2024-12-17 11:05:23

如果您没有那么多根节点,则可以使用延迟加载机制,请参阅例如 sitepen 上的这篇文章

不过请注意,它与 dojo 1.4 - 1.5.1 配合良好,在 dojo 1.6.1 中有一些JsonRestStore 的奇怪问题。

请参阅 stackoverflow 上的此问题

编辑以匹配澄清

我认为树不可能只在视图区域中构建节点。至少这对于标准 dijit.tree 是不可能的。

在我们的一个应用程序中,我们插入结构节点作为解决方法,即


root
---[1..30] - structure node 
  ---item 1
  ---item 2
  ...
---[31..60] - structure node
   ---item 31
   ---item 32
   ...
...

另一方面,听起来树网格与您想要的非常匹配,也许它可以与一些样式一起使用

If you don't have that many root nodes, you could use a lazy loading mechanism, see for example this article at sitepen

be warned though, it works well with dojo 1.4 - 1.5.1, in dojo 1.6.1 there are some strange issues with the JsonRestStore.

See this question at stackoverflow

edit to match the clarification

I don't think it's possible for the tree to only build the nodes in the view area. At least this is not possible with the standard dijit.tree.

In one of our applications we inserted structure nodes as a workaround, i.e.


root
---[1..30] - structure node 
  ---item 1
  ---item 2
  ...
---[31..60] - structure node
   ---item 31
   ---item 32
   ...
...

on the other hand, it sounds like the tree grid is a close match to what you want, maybe it could work with a bit of styling

小…楫夜泊 2024-12-17 11:05:23

这可能是一个迟到的回应,但我正在做的一个项目也有同样的问题,并且应用程序必须在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 所花费的时间最多的部分,但这并不比加载大型网页更糟糕。数据已加载,我们注册了我们的事件钩子,展开具有 5,000 个项目的节点相当快,我们基本上只是切换 CSS 显示设置来展开/折叠文件夹,因此您基本上受限于浏览器本身的执行方式

当然,可以创建替代结构来表示树数据,但我想你明白了。我们将树的核心功能封装在一个类中,其中包含一些虚拟事件来表示何时单击某个项目以及该类的用户仅使用 dojo.connect() 来连接。感兴趣的树事件。

旁注:为所有项目创建 dijit.Tooltip 实例是导致性能下降的一个重要因素。为了解决这个问题,我们直接使用 dijit.showTooltip() 和 dijit.hideTooltip() 来管理工具提示渲染,而不是创建 dijit.Tooltip 实例。

对我们来说一件不幸的事情是被困在 IE7 中。即使系统有足够的 RAM,IE7 在处理大型数据集时也会降低整体性能。 IE8和IE9在这方面有了很大的改进。

This may be a late response, but a project I'm working on had the same problem, and the application has to run in IE7, so the performance was definitely not good. The core problem is when you have many nodes at one level, and we were dealing with hundreds if not over a thousand, causing the dreaded script-running dialog to popup.

We recently replaced the use of dijit.Tree with our own tree implementation, finding the extra abstraction of the backing store unnecessary since the server already was the data abstraction layer. Hence, we have the server generate an HTML fragment, using divs and spans to represent the structure of the tree and custom attributes to associate data for each node. CSS is used to format the data visually.

This approach leverages the intrinsic capability of the browser to process HTML. A few connections to mouse and keyboard events allows us to get full tree-based functionality (including tooltips for nodes) in an efficient manner. Here's a simplified example of the type of HTML structure our server generates:

<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>
            ...

The class names are used for CSS formatting. The various my-* attributes are the custom attributes that the client-side of the application uses to tie actions to when the user selects a tree node. We use a JSON string to represent in data, so dojo.fromJson() can be used on the attribute to get the data associated with the node (we internally cache the object created with the DOM node, so fromJson() does not have to be used each time the data is accessed.

Our load times have drastically improved, with now the browser itself being the one taken the most amount of time to parse the HTML, but it is no worse than loading a large web page. Once the HTML data is loaded and we registered our event hooks, expanding a node with 5,000 items is fairly quick. We basically just toggle CSS display setting to expand/collapse folders, so you are basically limited to how the browser itself performs.

Of course, one can create alternative structures to represent tree data, but I think you get the idea. We encapsulate the core functionality of the tree in a class with some virtual events to represent when an item is clicked and other tree actions. The user of the class just uses dojo.connect() to connect to which tree events of interest.

Side Note: Creating dijit.Tooltip instances for all the items was a significant factor in slow performance. To get around that, we manage tooltip rendering ourselves by using dijit.showTooltip() and dijit.hideTooltip() directly vs creating dijit.Tooltip instances.

One unfortunate thing for us is being stuck in IE7. IE7 degrades overall performance-wise when deal with large data sets, even if the system has plenty of RAM. IE8 and IE9 are much improved in this regard.

千纸鹤 2024-12-17 11:05:23

您可以尝试使用 Lazy Tree Grid 以及查询读取存储。这就是你所需要的。在父母急切加载之后延迟加载孩子。还可以使用grid.rowsPerPage控制需要加载的父元素的数量

You can try using Lazy Tree Grid along with Query Read Store. This does what you need. Lazy loading of children after eager loading of parents. Number of parent elements that needs to be loaded can also be controlled, with the grid.rowsPerPage

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文