Hi,
I’m running the following example:
<!DOCTYPE html>
<html>
<head>
<title>Performance number of nodes</title>
<meta charset="UTF-8">
</head>
<body onload="init()">
<span id="myNumberOfNodes"></span>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:1000px"></div>
<div id="myOverviewDiv" style="border: solid 1px black; width:300px; height:300px"></div>
<script src="go.js"></script>
<script id="code">
function init() {
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram =
$(go.Diagram, "myDiagramDiv", // create a Diagram for the DIV HTML element
{ // enable undo & redo
"undoManager.isEnabled": true
});
// define a simple Node template
myDiagram.nodeTemplate =
$(go.Node, "Auto", // the Shape will go around the TextBlock
// new go.Binding("location", "location", go.Point.parse),
// new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape, "RoundedRectangle",
{ strokeWidth: 0, fill: "white" }, // default fill is white
// Shape.fill is bound to Node.data.color
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 8 }, // some room around the text
// TextBlock.text is bound to Node.data.key
new go.Binding("text", "key"))
);
var myOverview =
$(go.Overview, "myOverviewDiv", { observed: myDiagram, updateDelay: 5000 });
// but use the default Link template, by not setting Diagram.linkTemplate
// create the model data that will be represented by Nodes and Links
let nodes = []
let links = []
let numberOfNodes = 50000
for (let i = 0; i < numberOfNodes; ++i) {
nodes.push({ key: `Alpha${i}`, color: "lightblue", location: "0 0" })
links.push({ from: `Alpha${i}`, to: `Alpha${i+1}` })
}
myDiagram.model = new go.GraphLinksModel(nodes, links);
document.getElementById("myNumberOfNodes").innerText = `Number of nodes: ${numberOfNodes}`
}
</script>
</body>
</html>
The diagram takes some time to initialize but when it is loaded, I can manipulate the nodes smoothly without any “lagging experience”.
However, when I introduce one or two way databinding on the location, manipulating a nodes position feels very laggy.
I can imagine that two way data binding would influence the location manipulation performance but why is one way data binding influencing this that much? It this expected behavior or am I missing something? Furthermore, I would like to update my model when the user has finished dragging a node; would it help to listen to SelectionMoved
events and update the model manually instead of having a two way binding on the location? If I recall correctly, it is not possible to configure the two way data binding that it will only be evaluated on user interaction end.
Thanks!