Skip to content

DYN-8801 UpdateLayout Performance#16267

Closed
RobertGlobant20 wants to merge 1 commit into
DynamoDS:masterfrom
RobertGlobant20:DYN-8801-UpdateLayout-Performance
Closed

DYN-8801 UpdateLayout Performance#16267
RobertGlobant20 wants to merge 1 commit into
DynamoDS:masterfrom
RobertGlobant20:DYN-8801-UpdateLayout-Performance

Conversation

@RobertGlobant20

Copy link
Copy Markdown
Contributor

Purpose

Reduce the number of calls to UpdateLayout (Measure - Arrange) when loading a graph
I've added the functionality of serialize into the dyn file the NodeView.Width and NodeView.Height (this values will be set on the NodeView.SizeChanged event) also when loading the graph the Width and Height will be deserialized.
Also added the functionality that we opening the graph, the Width and Height will be set to elements in the NodeView to avoid extra calls to MeasureOverride() and ArrangeOverride() this will produce some performance improvements avoiding calls to UpdateLayout().
Finally I modified the PublicAPI.Unshipped adding the new properties for Width and Height.

Important Considerations:
This change only will work with new graphs (if is an old graph we need to re-saved or use File -> Save As for creating a new dyn file) due that we need the Width and Height stored in the dyn file.

Here you can see the result got before/after my changes (when testing with the graph Manekin-0.50):
For getting the number of calls to Measure() and Arrange() I added the methods NodeView.ArrangeOverride() and NodeView.MeasureOverrride() and add code for logging in a txt file the calls to each one (I did this for the master branch and for my feature branch), the loading time was calculated manually with the Clock app and interacting with Dynamo manually.

image

Declarations

Check these if you believe they are true

  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated
  • This PR contains no files larger than 50 MB
  • This PR introduces new feature code involve network connecting and is tested with no-network mode.

Release Notes

Reduce the number of calls to UpdateLayout (Measure - Arrange) when loading a graph

Reviewers

@reddyashish @zeusongit

FYIs

I've added the functionality of serialize into the dyn file the NodeView.Width and NodeView.Height (this values will be set on the NodeView.SizeChanged event) also when loading the graph the Width and Height will be deserialized.
Also added the functionality that we opening the graph, the Width and Height will be set to elements in the NodeView to avoid extra calls to MeasureOverride() and ArrangeOverride() this will produce some performance improvements avoiding calls to UpdateLayout().
Finally I modified the PublicAPI.Unshipped adding the new properties for Width and Height.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the ticket for this pull request: https://jira.autodesk.com/browse/DYN-8801

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR reduces redundant layout passes by persisting and reusing node dimensions when loading graphs, avoiding extra Measure/Arrange calls.

  • Introduces Width and Height properties on NodeModel/NodeViewModel and serializes them into .dyn files
  • Applies stored sizes in NodeView during graph load and captures changes via SizeChanged
  • Updates WorkspaceModel loading logic, PublicAPI.Unshipped, and removes JsonIgnore to support the new properties

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/DynamoCoreWpf/Views/Core/NodeView.xaml.cs Apply persisted node size on load; track SizeChanged event
src/DynamoCoreWpf/Views/Core/NodeView.xaml Hook up SizeChanged="topControl_SizeChanged"
src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs Add serializable Width/Height properties and docs
src/DynamoCore/PublicAPI.Unshipped.txt Document new WorkspaceModel.Width/Height API
src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs Persist and restore node width/height on graph load
src/DynamoCore/Graph/ModelBase.cs Remove JsonIgnore on base Width/Height properties
Comments suppressed due to low confidence (4)

src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs:733

  • The XML summary is incorrect—this property represents the node's width, not its Y position. Update the comment accordingly.
///     Returns or set the Y position of the Node.

src/DynamoCoreWpf/Views/Core/NodeView.xaml.cs:866

  • [nitpick] Method names should use PascalCase and follow event-handler conventions (e.g., OnTopControlSizeChanged).
private void topControl_SizeChanged(object sender, SizeChangedEventArgs e)

src/DynamoCoreWpf/ViewModels/Core/NodeViewModel.cs:736

  • Consider adding unit tests to verify Width/Height properties serialize and deserialize correctly and are applied in NodeView.
public double Width

src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs:2500

  • Assigning width/height unconditionally will reset dimensions to 0 for old graphs lacking these fields. Consider guarding assignments (e.g. if (nodeViewInfo.Width > 0)).
nodeModel.Width = nodeViewInfo.Width;

Comment on lines +202 to +203
//The default Width and Height values for nodes is 100 so only should be executed on graph loading
if (ViewModel.Width > 100 && ViewModel.Height > 100)

Copilot AI Jun 4, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The literal 100 is a magic number. Extract it into a well-named constant (e.g., DefaultNodeSize) for clarity and reuse.

Suggested change
//The default Width and Height values for nodes is 100 so only should be executed on graph loading
if (ViewModel.Width > 100 && ViewModel.Height > 100)
//The default Width and Height values for nodes is defined as DefaultNodeSize so only should be executed on graph loading
if (ViewModel.Width > NodeConstants.DefaultNodeSize && ViewModel.Height > NodeConstants.DefaultNodeSize)

Copilot uses AI. Check for mistakes.
Comment on lines +203 to +208
if (ViewModel.Width > 100 && ViewModel.Height > 100)
{
nodeBorder.Width = ViewModel.Width;
nodeBorder.Height = ViewModel.Height;
nameBackground.Width = ViewModel.Width;
Width = ViewModel.Width;

Copilot AI Jun 4, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combining both dimension checks means a node with one dimension below threshold won't be resized even if the other exceeds it. Consider separate checks or clearer intent.

Suggested change
if (ViewModel.Width > 100 && ViewModel.Height > 100)
{
nodeBorder.Width = ViewModel.Width;
nodeBorder.Height = ViewModel.Height;
nameBackground.Width = ViewModel.Width;
Width = ViewModel.Width;
// Resize the node if its width exceeds the threshold of 100.
if (ViewModel.Width > 100)
{
nodeBorder.Width = ViewModel.Width;
nameBackground.Width = ViewModel.Width;
Width = ViewModel.Width;
}
// Resize the node if its height exceeds the threshold of 100.
if (ViewModel.Height > 100)
{
nodeBorder.Height = ViewModel.Height;

Copilot uses AI. Check for mistakes.
@RobertGlobant20

Copy link
Copy Markdown
Contributor Author

This is an example of the comparison of the number of calls to Measure() and Arrange() in a file with 9 different nodes (lef side with my changes, right side without my changes)
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants