I modified your sample as follows:
Index.aspx. I modified how the timing is measured (see onTreeDataLoad), I suppressed the animation for the tree and removed your AfterItemExpand.
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register TagPrefix="ext" Namespace="Ext.Net" Assembly="Ext.Net" %>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Index</title>
</head>
<body>
<ext:ResourceManager ID="ResourceManager1" runat="server" SourceFormatting="True"
ScriptMode="Debug">
</ext:ResourceManager>
<script>
startTimeMs = 0;
function loadTree() {
App.treePanel.el.mask('Loading...', 'x-mask-loading');
startTimeMs = new Date().getTime();
Ext.Ajax.request(
{
url: '/TreePanel_Advanced/TreeGrid/NodeLoadOriginal',
method: 'GET',
params: {},
success: function onSuccess(result, request) {
onTreeDataLoad(App.treePanel, result);
},
failure: function (result, request) {
App.treePanel.el.unmask();
Ext.net.DirectEvent.showFailure(result);
}
});
}
function onTreeDataLoad(treePanel, result) {
var nodes = Ext.JSON.decode(result.responseText).result;
startTimeMs = new Date().getTime();
treePanel.setRootNode(nodes[0]);
treePanel.getRootNode().expand(true);
treePanel.el.unmask();
alert((new Date().getTime() - startTimeMs) / 1000 + 'seconds');
}
</script>
<ext:Viewport ID="Viewport1" runat="server" Layout="fit">
<Items>
<ext:TreePanel ID="treePanel" runat="server" Title="Test tree" IDMode="Static" UseArrows="true" Animate="False"
RootVisible="True">
<TopBar>
<ext:Toolbar ID="Toolbar1" runat="server">
<Items>
<ext:Button ID="Button1" runat="server" Text="Load Tree">
<Listeners>
<Click Handler="loadTree();">
</Click>
</Listeners>
</ext:Button>
</Items>
</ext:Toolbar>
</TopBar>
<Fields>
<ext:ModelField Name="Tag" Type="String" />
<ext:ModelField Name="TagInstance" Type="Int" />
<ext:ModelField Name="State" Type="String" />
<ext:ModelField Name="StateId" Type="Int" />
<ext:ModelField Name="Command" Type="String" />
<ext:ModelField Name="HasNotes" Type="Boolean" />
<ext:ModelField Name="IsUsedByACanvas" Type="Boolean" />
<ext:ModelField Name="PerformanceIndicatorId" Type="Int" />
</Fields>
<ColumnModel>
<Columns>
<ext:TreeColumn ID="TreeColumn1" runat="server" Text="Title" Width="250" Sortable="false"
DataIndex="text" />
<ext:Column ID="CommandColumn" runat="server" DataIndex="Command" Text=" " Width="30"
Sortable="false">
</ext:Column>
<ext:Column ID="TagColumn" runat="server" DataIndex="Tag" Text="Tag" Width="80" Sortable="false">
</ext:Column>
<ext:Column ID="TagInstanceColumn" runat="server" DataIndex="TagInstance" Text="Tag Instance"
Width="100" Sortable="false">
</ext:Column>
<ext:Column ID="StateColumn" runat="server" DataIndex="State" Text="State" Width="130"
Sortable="false">
</ext:Column>
<ext:CheckColumn ID="HasNotesColumn" runat="server" DataIndex="HasNotes" Text="Has Notes"
Sortable="false" Width="90" Align="Center">
</ext:CheckColumn>
<ext:CheckColumn ID="IsUsedByACanvasColumn" runat="server" DataIndex="IsUsedByACanvas"
Text="Used by a Canvas" Sortable="false" Width="120" Align="Center">
</ext:CheckColumn>
</Columns>
</ColumnModel>
<Root>
<ext:Node NodeID="0" Text="Root" Leaf="True">
</ext:Node>
</Root>
<%-- <Listeners>--%>
<%-- <AfterItemExpand Handler="alert((new Date().getTime() - startTimeMs)/1000 + 'seconds');"></AfterItemExpand>--%>
<%-- </Listeners>--%>
</ext:TreePanel>
</Items>
</ext:Viewport>
</body>
</html>
I changed the TreeController.cs to add more depth to the tree. I renamed your original NodeLoad function NodeLoadOriginal.
public class TreeGridController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult NodeLoadOriginal(string node)
{
NodeCollection nodes = new Ext.Net.NodeCollection();
Node root = new Node();
root.Text = node;
root.NodeID = node;
nodes.Add(root);
for (int i = 0; i < 400; i++)
{
Node treeNode = new Node();
treeNode.CustomAttributes.Add(new ConfigItem("Tag", "Tag", ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("TagInstance", "0", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("State", "State" + i, ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("StateId", "0" + i, ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("Command", "Command" + i, ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("HasNotes", "true", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("IsUsedByACanvas", "false", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("PerformanceIndicatorId", "0", ParameterMode.Raw));
treeNode.Text = i.ToString();
treeNode.NodeID = node + i;
treeNode.Leaf = true;
root.Children.Add(treeNode);
}
return this.Direct(nodes);
}
public ActionResult NodeLoad(string node)
{
NodeCollection nodes = new Ext.Net.NodeCollection();
Node root = new Node();
root.Text = node;
root.NodeID = node;
nodes.Add(root);
IDictionary<int, Node> allNodes = new Dictionary<int, Node>();
for (int i = 0; i < 400; i++)
{
Node treeNode = new Node();
allNodes.Add(i, treeNode);
treeNode.CustomAttributes.Add(new ConfigItem("Tag", "Tag", ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("TagInstance", "0", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("State", "State" + i, ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("StateId", "0" + i, ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("Command", "Command" + i, ParameterMode.Value));
treeNode.CustomAttributes.Add(new ConfigItem("HasNotes", "true", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("IsUsedByACanvas", "false", ParameterMode.Raw));
treeNode.CustomAttributes.Add(new ConfigItem("PerformanceIndicatorId", "0", ParameterMode.Raw));
treeNode.Text = i.ToString();
treeNode.NodeID = node + i;
treeNode.Leaf = true;
}
for (int i = 0; i < 400; i++)
{
if ((i%100) == 0)
{
root.Children.Add(allNodes[i]);
}
else if (i < 10)
{
allNodes[10].Children.Add(allNodes[i]);
allNodes[10].Leaf = false;
}
else if ((i%10) == 0)
{
allNodes[ (i / 100) * 100 ].Children.Add(allNodes[i]);
allNodes[ (i / 100) * 100 ].Leaf = false;
}
else
{
allNodes[ 10 * (i / 10)].Children.Add(allNodes[i]);
allNodes[10* (i / 10)].Leaf = false;
}
}
return this.Direct(nodes);
}
}
Now, running the changed sample in Chrome using the original tree structure that you had takes about
: 0.5s.
Running my version that adds up to three levels (excluding the root) takes: 1.5s. It seems that adding a level decreases the performance by 100%. You could play with this tree by adding more levels and see what the performance is.
Here are some points I want to make:
1. Did you try the json file I made available through the link? The problem is the structure of the data. In my case, the depth of the tree is 7, i.e. there are paths that have 7 nodes. In your original sample the tree is basically flat. I think that's where things slow down, the more levels you have in the tree the performance will degrade drastically. In my application I cannot return flat data. In the end this is what trees are for, to display hierarchical data.
2. I compared loading the same data (my data) between version Ext.Net 1.x (Ext Js 3.4) and Ext.Net 2.x (Ext Js 4.1.1), and there is a huge performance dip between the two versions. Again for the same data.
In think whatever they did in ExtJs 4 it slowed down the rendering process of the tree.
Thanks