GoJS diagram drawing very slow

We are using gojs for creating tree view. below is the sample data for single node.

atn:‘HU’
av:’/0%’
eu:’’
ix:17.24624
ixq:192
ixv:‘17.2%’
key:1
mIx:0
mTi:28311655
parent:0
s:’’
sc:’#4169E1
td:‘HU’
tg:‘G’
ti:28356553
tn:‘PHIGROUP001’
tp:‘0’
w:1
wc:’#FE0000

We have 11,000 nodes. I have also attached sample diagram image. It tooks 35-40 seconds for creating this diagram. This is very poor performance by gojs library.
img_20210906

How we can optimize this drawing time. We need to bring it below 3 seconds. Please provide solution.

I just tried modifying the Tree View sample, GoJS Tree View, to generate a tree consisting of 11000 nodes. Typical load time on my not-so-fast machine is about 5 seconds.

What is your node template? If it’s very complex, it might be slow to actually copy and initialize all of those nodes and links.

This is our node template. We are ready to extend our support. Only, if you have proper solution.

 // Build GoJs Treeview
  loadTree() {
    let tempThis = this;
    this.goTreeDiagram =
      this.$(go.Diagram, "treeViewDiv",
        {
          hoverDelay: 2,
          contentAlignment: go.Spot.TopLeft,
          padding: new go.Margin(0, 0, 0, 0),
          allowMove: false,
          allowCopy: false,
          allowDelete: false,
          allowHorizontalScroll: true,
          scale: 1,
          minScale: 1,
          maxScale: 1,
          maxSelectionCount: 1,
          layout:
            this.$(go.TreeLayout,
              {
                alignment: go.TreeLayout.AlignmentStart,
                angle: 0,
                compaction: go.TreeLayout.CompactionNone,
                layerSpacing: 16,
                layerSpacingParentOverlap: 1,
                nodeIndentPastParent: 1.0,
                nodeSpacing: 7,
                nodeIndent: 7,
                setsPortSpot: false,
                setsChildPortSpot: false
              }),
          "animationManager.isEnabled": false
        });

    this.goTreeDiagram.click = function (e, obj) {
      jQuery("#context-menu-tgTree").hide();
      tempThis.selectedNode.isSelected = true;
    };

    this.goTreeDiagram.commandHandler.canDecreaseZoom = function (factor) {
      if (factor === undefined)
        factor = 1.0 / this.zoomFactor;
      var diagram = tempThis.goTreeDiagram;
      if (diagram === null)
        return false;
      if (diagram.autoScale !== go.Diagram.None)
        return false;
      var newscale = diagram.scale * factor;
      if (newscale < diagram.minScale || newscale > diagram.maxScale)
        return false;
      return diagram.allowZoom;
    };
    this.goTreeDiagram.commandHandler.canIncreaseZoom = function (factor) {
      if (factor === undefined)
        factor = 1.0 / this.zoomFactor;
      var diagram = tempThis.goTreeDiagram;
      if (diagram === null)
        return false;
      if (diagram.autoScale !== go.Diagram.None)
        return false;
      var newscale = diagram.scale * factor;
      if (newscale > diagram.maxScale || newscale < diagram.minScale)
        return false;
      return diagram.allowZoom;
    };

    // Build Tree Node Layout.
    this.goTreeDiagram.nodeTemplate =
      this.$(go.Node,
        {
          // no Adornment: instead change panel background color by binding to Node.isSelected
          selectionAdorned: false,
          click: function (e, obj) {
            jQuery("#context-menu-tgTree").hide();
            if (obj == null)
              return;
            tempThis.selectedNode = obj.part;
            if (tempThis.searchValue == '') {
              // this will fill blue color to the current top node 
              if (obj.part.data.key != tempThis.topNode.data.key) {
                tempThis.topNode.findObject("TEXTBLOCK").stroke = tempThis.selectionColor;
                tempThis.topNode.findObject("TEXTBLOCK").font = "bold 14px/20px Roboto, sans-serif";
                tempThis.topNode.findObject("nodeIconText").stroke = tempThis.selectionColor;
              }
            }
            if (e.alt && obj.part.data.tg == "G") {
              window.open(document.baseURI + "successtree/" + obj.part.data.key + '/sid/' + CommonMethods.GetUserDetails().ConfigurationId, '_blank');
              obj.part.isSelected = true;
              e.handled = false;
            }
            if (tempThis.previousClickedNode != null && tempThis.highlightedList.length > 0
              && tempThis.highlightedList.some(n => n.part.data.ti == tempThis.previousClickedNode.data.ti)) {
              tempThis.previousClickedNode.findObject("TEXTPANEL").background = tempThis.hightLightColor;
            }
            tempThis.previousClickedNode = tempThis.selectedNode;

            // if (tempThis.searchNodeCollection) {
            //   tempThis.searchNodeCollection.each(function (n) {
            //     if (obj.part.data.atn != n.data.atn) {
            //       tempThis.updateNodeStyle(n);
            //     }
            //   });
            // }
            tempThis.searchNodeUpdateCommon(obj);
          },
          // a custom function to allow expanding/collapsing on double-click
          // this uses similar logic to a TreeExpanderButton
          doubleClick: function (e, obj) {
            //var cmd = tempThis.goTreeDiagram.commandHandler;
            let node = obj.part;
            tempThis.topNode.findObject("TEXTBLOCK").stroke = tempThis.themeName == Constants.themeDetails.dark.name ? "#fff" : "#444";
            tempThis.topNode.findObject("TEXTBLOCK").font = "14px/20px Roboto, sans-serif";
            tempThis.topNode.findObject("nodeIconText").stroke = tempThis.themeName == Constants.themeDetails.dark.name ? "#fff" : "#444";
            tempThis.topNode = obj.part;
            if (tempThis.searchValue == '') {
              if (node.data.tg == "G") {
                tempThis.onTreeNodeDoubleClick.emit({
                  gid: node.data.key,
                  gname: node.data.atn,
                  trailPath: tempThis.GetBreadCrumbsSeq(node),
                  searchedvalue: tempThis.searchValue
                });
              }
            } else {
              tempThis.onSearchTagorGroupDoubleClick.emit({
                searchtorg: node,
                searchedvalue: tempThis.searchValue
              });
            }

            // if (tempThis.searchNodeCollection) {
            //   tempThis.searchNodeCollection.each(function (n) {
            //     if (obj.part.data.atn != n.data.atn) {
            //       tempThis.updateNodeStyle(n);
            //     }
            //   });
            // }
            tempThis.searchNodeUpdateCommon(obj);
          },
          // mouseHover: function (e, obj) {
          //   var node = obj.part;
          //   let tp = node.findObject("TEXTPANEL");
          //   if (tp.background != '#ffff00')
          //     tp.background = "#e0f7ff";
          // },
          // mouseEnter: function (e, obj) {
          //   var node = obj.part;
          //   let tp = node.findObject("TEXTPANEL");
          //   // if (tp.background != '#ffff00')
          //   tp.background = "#e0f7ff";
          // },
          // mouseLeave: function (e, obj) {
          //   var node = obj.part;
          //   // let tp = node.findObject("TEXTPANEL");
          //   // // if (tp.background != '#ffff00')
          //   // tp.background = "transparent";
          // },
        },
        {
          contextMenu:
            this.$(go.HTMLInfo, {
              mainElement: document.getElementById("context-menu-tgTree"),
              show: function (obj, diagram, tool) {
                jQuery("#context-menu-st").hide();
                if (obj == null)
                  return;
                var node = obj.part;
                tempThis.selectedNode = node;
                if (node.data.tg == "T") {
                  tempThis.stGroupId = tempThis.selectedNode.data.parent;
                  jQuery("#context-menu-tgTree #lp_nfbtnSetup").hide();
                  jQuery("#context-menu-tgTree #lp_sbsbtnSetup").hide();
                  jQuery("#context-menu-tgTree #lp_btnTrackMinIndex").hide();
                  jQuery("#context-menu-tgTree #lp_btnMinTagsList").hide();

                  jQuery("#context-menu-tgTree #lp_btnTrack").show();
                  jQuery("#context-menu-tgTree #lp_btnAddToWatchList").show();
                  jQuery("#context-menu-tgTree #lp_btnComments").show();
                  jQuery("#context-menu-tgTree #lp_btnAlarmHistory").show();
                  jQuery("#context-menu-tgTree #lp_btnSTTrend").show();

                  if (jQuery("#context-menu-tgTree #lp_btnSTTrend").hasClass("disabled-content")) {
                    jQuery("#context-menu-tgTree #lp_btnSTTrend").removeClass("disabled-content");
                  }

                  if (tempThis.isTATF) {
                    jQuery("#context-menu-tgTree #lp_btnComments").addClass("disabled-content");
                    jQuery("#context-menu-tgTree #lp_btnTrack").addClass("disabled-content");
                  }
                }
                else {
                  tempThis.stGroupId = tempThis.selectedNode.data.key;
                  jQuery("#context-menu-tgTree #lp_nfbtnSetup").show();
                  jQuery("#context-menu-tgTree #lp_sbsbtnSetup").show();
                  jQuery("#context-menu-tgTree #lp_btnTrackMinIndex").show();
                  jQuery("#context-menu-tgTree #lp_btnMinTagsList").show();
                  jQuery("#context-menu-tgTree #lp_btnSTTrend").show();

                  jQuery("#context-menu-tgTree #lp_btnTrack").hide();
                  jQuery("#context-menu-tgTree #lp_btnAddToWatchList").hide();
                  jQuery("#context-menu-tgTree #lp_btnComments").hide();
                  jQuery("#context-menu-tgTree #lp_btnAlarmHistory").hide();
                  jQuery("#context-menu-tgTree #lp_btnSTTrend").addClass("disabled-content");

                  if (node.findTreeChildrenNodes() != null) {
                    node.findTreeChildrenNodes().each(function (child) {
                      if (child.data.tg == "T" && child.data.parent == tempThis.stGroupId) {
                        if (jQuery("#context-menu-tgTree #lp_btnSTTrend").hasClass("disabled-content")) {
                          jQuery("#context-menu-tgTree #lp_btnSTTrend").removeClass("disabled-content");
                        }
                      }
                    });
                  }

                  if (tempThis.isTATF) {
                    jQuery("#context-menu-tgTree #lp_btnTrackMinIndex").addClass("disabled-content");
                    jQuery("#context-menu-tgTree #lp_btnMinTagsList").addClass("disabled-content");
                    jQuery("#context-menu-tgTree #lp_btnComments").addClass("disabled-content");
                    jQuery("#context-menu-tgTree #lp_btnTrack").addClass("disabled-content")
                  }
                }
                let cxElement = document.getElementById("context-menu-tgTree");
                // Now show the whole context menu element
                cxElement.style.display = "block";
                // tempThis.currentMousePos.x = tempThis.currentMousePos.x >= ($(document).width() - jQuery("#context-menu-tgTree").width()) ? (tempThis.currentMousePos.x - jQuery("#context-menu-tgTree").width()) : tempThis.currentMousePos.x;
                tempThis.currentMousePos.y = tempThis.currentMousePos.y >= ($(document).height() - jQuery("#context-menu-tgTree").height()) ? (tempThis.currentMousePos.y - jQuery("#context-menu-tgTree").height()) : tempThis.currentMousePos.y;
                cxElement.style.left = tempThis.currentMousePos.x + "px";
                cxElement.style.top = tempThis.currentMousePos.y + "px";

                // if (tempThis.searchNodeCollection) {
                //   tempThis.searchNodeCollection.each(function (n) {
                //     if (obj.part.data.atn != n.data.atn) {
                //       tempThis.updateNodeStyle(n);
                //     }
                //   });
                // }
                tempThis.searchNodeUpdateCommon(obj);
              }
            })
        },
        this.$("TreeExpanderButton",
          {
            name: "expanderButton",
            // "_buttonFillOver": "rgba(0,128,255,0.25)",
            // "_buttonStrokeOver": null,
            // "ButtonBorder.fill":  this.themeName.toLowerCase() == 'light' ? 'whitesmoke' : this.themeTXTColor,
            // "ButtonBorder.stroke": null,
            // name: "expanderButton",
            "ButtonBorder.fill": this.themeName.toLowerCase() == 'light' ? "whitesmoke" : this.themeTXTColor,
            "ButtonBorder.stroke": null,
            "_buttonFillOver": this.themeName.toLowerCase() == 'light' ? "rgba(0,128,255,0.25)" : "#a2a2a2",
            "_buttonStrokeOver": null,
            "_buttonFillPressed": null, // on pressed filled color
            "_buttonStrokePressed": null, // on pressed stroke
            // "ButtonIcon.fill": null,
            // "ButtonIcon.stroke": this.themeTXTColor,

            padding: new go.Margin(5, 0, 5, 0),
            click: function (e, obj) {  // OBJ is the Button
              var node = obj.part;  // get the Node containing this Button
              if (node === null) return;
              //tempThis.excolCalled = true;
              e.handled = true;
              tempThis.expandCollapse(node);
              tempThis.UpdateVisible();
              //tempThis.excolCalled = false;
              //tempThis.expandNode(node);
            }
          }
        ),
        this.$(go.Panel, "Horizontal",
          {
            name: "TEXTPANEL",
            position: new go.Point(18, 0),
            padding: new go.Margin(5, 5, 5, 5)
          },
          new go.Binding("background", "isSelected", function (s) {
            // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
            //   return n.findObject("TEXTPANEL").background;
            // else
            return (s ? tempThis.selectionColor : tempThis.transparentColor);
          }).ofObject(),
          // not in use right now  
          new go.Binding("fill", "isHighlighted", function (h) { return h ? tempThis.hightLightColor : tempThis.transparentColor; }).ofObject(),
          // this.$(go.Picture,
          //   {
          //     width: 16, heightposition: new go.Point(18, 0): 16,
          //     margin: new go.Margin(0, 4, 0, 0),
          //     imageStretch: go.GraphObject.Uniform
          //   },
          //   new go.Binding("source", "isTreeLeaf", function (s) { return s ? "./assets/img/icon/ST_Tag_16x16.png" : "./assets/img/icon/ST_Group_16x16.png"; }).ofObject(),
          // ),
          this.$(go.TextBlock,
            {
              name: "nodeIconText",
              stroke: '#444',
              margin: new go.Margin(0, 3, 0, 2),
              font: '16px FontAwesome',
              editable: false,
              isMultiline: false
            },
            new go.Binding("visible", "isTreeLeaf", function (t) { return t; }),
            new go.Binding("stroke", "isSelected", function (s) {
              // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
              //   return "#444";
              // else
              return (s ? "#fff" : tempThis.themeTXTColor);
            }).ofObject()
          ),
          this.$(go.Shape,
            {
              name: "nodeShape",
              figure: "Rectangle",
              width: 4,
              height: 18,
              spot1: go.Spot.Center,
              spot2: go.Spot.Center,
              strokeWidth: 0,
              margin: new go.Margin(-2, 5, 0, 0)
            },
            new go.Binding("visible", "tg", function (d) { return !tempThis.isTATF; }),
            new go.Binding("fill", "c", function (c) { return c; })
          ),
          this.$(go.TextBlock, { name: "TEXTBLOCK" },
            {
              stroke: "#444",
              font: "14px/20px  Roboto, sans-serif"
            },
            new go.Binding("text", "atn"),
            {
              toolTip: this.$("ToolTip",
                new go.Binding("visible", "td", function (d) { return d != null && d != undefined && d.length > 0 ? true : false; }),
                this.$(go.TextBlock,
                  new go.Binding("text", "td", function (d) { return d != null && d != undefined ? d : ""; }),
                  { font: this.goJS_tooltip_font }
                )
              )
            },
            new go.Binding("stroke", "isSelected", function (s) {
              // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
              //   return "#444";
              // else
              return (s ? "#fff" : tempThis.themeTXTColor);
            }).ofObject()
          )
        )// end Horizontal Panel
      );  // end Node

    // without lines
    this.goTreeDiagram.linkTemplate = this.$(go.Link);

    // // with lines
    // this.goTreeDiagram.linkTemplate =
    //   this.$(go.Link,
    //     {
    //       selectable: false,
    //       routing: go.Link.Orthogonal,
    //       fromEndSegmentLength: 4,
    //       toEndSegmentLength: 4,
    //       fromSpot: new go.Spot(0.001, 1, 7, 5),
    //       toSpot: go.Spot.Left
    //     },
    //     this.$(go.Shape,
    //       { stroke: 'gray', strokeWidth: 0.5 })
    //   );

    this.goTreeDiagram.addDiagramListener("InitialLayoutCompleted", function (e) {
      tempThis.rootNode = e.diagram.findTreeRoots().first();
      // // tempThis.rootNode.findObject("expanderButton").visible = false;
      tempThis.rootNode.collapseTree(3);
      // tempThis.goTreeDiagram.nodes.each(function (n) { n.wasTreeExpanded = false; });
      // tempThis.topNode = tempThis.goTreeDiagram.findNodeForKey(tempThis.gid);
      // tempThis.selectNode(tempThis.topNode);
      // //send seq
      // tempThis.onTreeLoad.emit({ trailPath: tempThis.GetBreadCrumbsSeq(tempThis.topNode) });
      // // tempThis.stopLoading();
      // tempThis.UpdateVisible();
      tempThis.timeOutIDs.push(
        setTimeout(() => {
          tempThis.SetNodeIcons();
          tempThis.feedReaminingData();
        }, 100)
      );
    });

    this.goTreeDiagram.model = new go.TreeModel(tempThis.initialDataSource);
  }

When I try your code, after commenting out all of the irrelevant stuff and code I cannot reproduce, I’m getting a lot of binding errors:

Binding error: undefined target property: fill on Panel([object Object])#6877

I recommend that you make sure that your code is working correctly before you worry about performance. One way to do that is to use the go-debug.js library. In either case, make sure you look at the console output for warning and error messages, some of which may appear even when using the release go.js library.

I am using Gojs library with angular framework. I do not receive any error in the console and code is running without error. Point is when nodes are more than 10,000 it takes time in rendering. For less nodes it’s works fine.

So, Point is we require details for how to improve performance when we have more than 10,000 tags.

But at least one of your Bindings is wrong, and I suspect the error does cause it to be slower.

          // not in use right now  
          new go.Binding("fill", "isHighlighted", function (h) { return h ? tempThis.hightLightColor : tempThis.transparentColor; }).ofObject(),

Here’s a complete sample using your code. Your code had a lot of unresolved dependencies, so I either stripped out the code (for example when dealing with HTML elements that I don’t know about) or implemented substitute properties. I don’t think anything I changed to get it to work stand-alone has any substantive impact on performance.

The whole 11000 node tree loads in 5-6 seconds, at least after caching the go.js library from unpkg.com:

<!DOCTYPE html>
<html>
<head>
  <title>Minimal GoJS Sample</title>
  <!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
  function init() {
    var $ = go.GraphObject.make;
    let tempThis = {
      selectionColor: "cyan",
      transparentColor: "transparent",
      highlightColor: "lime",
      themeTXTColor: "blue",
      isTATF: false,
      themeName: "light"
    };
    myDiagram =
      $(go.Diagram, "myDiagramDiv",
        {
          hoverDelay: 2,
          contentAlignment: go.Spot.TopLeft,
          padding: new go.Margin(0, 0, 0, 0),
          allowMove: false,
          allowCopy: false,
          allowDelete: false,
          allowHorizontalScroll: true,
          scale: 1,
          minScale: 1,
          maxScale: 1,
          maxSelectionCount: 1,
          layout:
            $(go.TreeLayout,
              {
                alignment: go.TreeLayout.AlignmentStart,
                angle: 0,
                compaction: go.TreeLayout.CompactionNone,
                layerSpacing: 16,
                layerSpacingParentOverlap: 1,
                nodeIndentPastParent: 1.0,
                nodeSpacing: 7,
                nodeIndent: 7,
                setsPortSpot: false,
                setsChildPortSpot: false
              }),
          "animationManager.isEnabled": false
        });

    // Build Tree Node Layout.
    myDiagram.nodeTemplate =
      $(go.Node,
        {
          // no Adornment: instead change panel background color by binding to Node.isSelected
          selectionAdorned: false,
        },
        $("TreeExpanderButton",
          {
            name: "expanderButton",
            "ButtonBorder.fill": tempThis.themeName.toLowerCase() == 'light' ? "whitesmoke" : tempThis.themeTXTColor,
            "ButtonBorder.stroke": null,
            "_buttonFillOver": tempThis.themeName.toLowerCase() == 'light' ? "rgba(0,128,255,0.25)" : "#a2a2a2",
            "_buttonStrokeOver": null,
            "_buttonFillPressed": null, // on pressed filled color
            "_buttonStrokePressed": null, // on pressed stroke

            padding: new go.Margin(5, 0, 5, 0),
          }
        ),
        $(go.Panel, "Horizontal",
          {
            name: "TEXTPANEL",
            position: new go.Point(18, 0),
            padding: new go.Margin(5, 5, 5, 5)
          },
          new go.Binding("background", "isSelected", function (s) {
            // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
            //   return n.findObject("TEXTPANEL").background;
            // else
            return (s ? tempThis.selectionColor : tempThis.transparentColor);
          }).ofObject(),
          // not in use right now  
          //!!! new go.Binding("fill", "isHighlighted", function (h) { return h ? tempThis.hightLightColor : tempThis.transparentColor; }).ofObject(),
          // $(go.Picture,
          //   {
          //     width: 16, heightposition: new go.Point(18, 0): 16,
          //     margin: new go.Margin(0, 4, 0, 0),
          //     imageStretch: go.GraphObject.Uniform
          //   },
          //   new go.Binding("source", "isTreeLeaf", function (s) { return s ? "./assets/img/icon/ST_Tag_16x16.png" : "./assets/img/icon/ST_Group_16x16.png"; }).ofObject(),
          // ),
          $(go.TextBlock,
            {
              name: "nodeIconText",
              stroke: '#444',
              margin: new go.Margin(0, 3, 0, 2),
              //font: '16px FontAwesome',
              editable: false,
              isMultiline: false
            },
            new go.Binding("visible", "isTreeLeaf", function (t) { return t; }),
            new go.Binding("stroke", "isSelected", function (s) {
              // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
              //   return "#444";
              // else
              return (s ? "#fff" : tempThis.themeTXTColor);
            }).ofObject()
          ),
          $(go.Shape,
            {
              name: "nodeShape",
              figure: "Rectangle",
              width: 4,
              height: 18,
              spot1: go.Spot.Center,
              spot2: go.Spot.Center,
              strokeWidth: 0,
              margin: new go.Margin(-2, 5, 0, 0)
            },
            new go.Binding("visible", "tg", function (d) { return !tempThis.isTATF; }),
            new go.Binding("fill", "c", function (c) { return c; })
          ),
          $(go.TextBlock, { name: "TEXTBLOCK" },
            {
              stroke: "#444",
              font: "14px/20px  Roboto, sans-serif"
            },
            new go.Binding("text", /*"atn"*/),
            {
              toolTip: $("ToolTip",
                new go.Binding("visible", "td", function (d) { return d != null && d != undefined && d.length > 0 ? true : false; }),
                $(go.TextBlock,
                  new go.Binding("text", "td", function (d) { return d != null && d != undefined ? d : ""; }),
                  //{ font: this.goJS_tooltip_font }
                )
              )
            },
            new go.Binding("stroke", "isSelected", function (s) {
              // if (n.findObject("TEXTPANEL").background == tempThis.hightLightColor)
              //   return "#444";
              // else
              return (s ? "#fff" : tempThis.themeTXTColor);
            }).ofObject()
          )
        )// end Horizontal Panel
      );  // end Node

    // without lines
    myDiagram.linkTemplate = $(go.Link);

    myDiagram.addDiagramListener("InitialLayoutCompleted", function (e) {
      tempThis.rootNode = e.diagram.findTreeRoots().first();
      if (tempThis.rootNode) tempThis.rootNode.collapseTree(3);
    });
    
    
    function makeTree(level, count, max, nodeDataArray, parentdata) {
      var numchildren = Math.floor(Math.random() * 10);
      for (var i = 0; i < numchildren; i++) {
        if (count >= max) return count;
        count++;
        var childdata = { key: count, parent: parentdata.key, text: count.toString() };
        nodeDataArray.push(childdata);
        if (level > 0 && Math.random() > 0.5) {
          count = makeTree(level - 1, count, max, nodeDataArray, childdata);
        }
      }
      return count;
    }

    // create a random tree
    var nodeDataArray = [{ key: 0 }];
    var max = 11000;
    var count = 0;
    while (count < max) {
      count = makeTree(3, count, max, nodeDataArray, nodeDataArray[0]);
    }
    myDiagram.model = new go.TreeModel(nodeDataArray);
  }
  </script>
</head>
<body onload="init()">
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
</body>
</html>

Thank you walter for your help. I will check my code and let you know the result.

Hi, I found one for loop which was taking 8-9 seconds. Now diagram working fine.
Now, I stuck at one more issue.
Is there any way to get list of visible nodes on present in screen area?

    var vis = [];
    myDiagram.nodes.each(n => {
      if (n.isVisible() && n.actualBounds.intersectsRect(myDiagram.viewportBounds)) vis.push(n);
    });

Part.isVisible is used to decide whether a Node or a Link isn’t hidden because it is in a collapsed subtree or group subgraph, in addition to just checking its visible property.

Diagram.viewportBounds is the area shown by the viewport.

Thank you walter for your help. It works fine.