Skip to content

#26696 - Performance issue continuation in Blazor WebApp #26841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Naganathan opened this issue Oct 13, 2020 · 2 comments
Closed

#26696 - Performance issue continuation in Blazor WebApp #26841

Naganathan opened this issue Oct 13, 2020 · 2 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved
Milestone

Comments

@Naganathan
Copy link

#26696, Continuation of this issue. still we are facing performance related issue for Web application after checked the given guidelines.

Guidelines for WebApp implementation

Please refer the below sample and video link.

Video link: Video

Sample file : Sample

In the above sample, we have rendered the node only when dragging and others are not re-rendered. Please refer to the below code example which we have used in a sample.

<div id="canvas" @onmousedown="@OnMouseDown" @onmousemove="@OnMouseMove" @onmouseup="@OnMouseUp" style="width: 100%;height: 700px;position:relative;width:100%; height:700px;position:relative;overflow:hidden;background:#ededed">
    <svg id="canvas_layer" width="@Width" height="@Height" xmlns="http://www.w3.org/2000/svg">
        <g>
            <g id="canvas_layer" style="pointer-events: all;" transform="translate(0,0),scale(1)">

                @if (firstRender)
                {
                    <--render all nodes initially-->
                    @foreach (Node node in Nodes)
                        @RenderNode(node);
                }
                @if (draggingNode != null)
                {
                    @RenderNode(draggingNode); <-- Node object passing as a parameter to render only when dragging--> 
                }
            </g>
        </g>
    </svg>
</div>

@code
{
    RenderFragment<Node> RenderNode = node => __builder =>
    {
        <g id="node_element" xmlns="http://www.w3.org/2000/svg">
            <rect id="@node.Id" x="@node.X" y="@node.Y" width="@node.Width" height="@node.Height" fill="blue" stroke-width="5"></rect>
        </g>
    };
}
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Oct 13, 2020
@captainsafia captainsafia self-assigned this Oct 13, 2020
@captainsafia captainsafia added this to the Discussions milestone Oct 13, 2020
@SteveSandersonMS
Copy link
Member

There are some problems in the code you've posted. The main two are:

  • Your firstRender flag stays as true all the time. It looks like you intend it to be false after the first render, but that's not what happens because of your logic in OnAfterRenderAsync. Note that the idea of only rendering a single node doesn't work anyway since that would cause all the other nodes to disappear. If you only want to render a subset of nodes, they have to be separate components.
  • You're calling StateHasChanged unnecessarily from many places. These are causing lots of unnecessary renders. You will at least double rendering performance by removing those.

The bigger issue is that onmousemove can fire hundreds of times per second, and every time that happens you're trying to re-render a component that produces many thousands of elements. In total this is doing a huge amount of work.

If you do want to run all that logic on .NET, the way I'd recommend is to split the rendering so that one component renders the static (not-currently-dragging) nodes, and a different one renders just the one being dragged and has the @onmousemove listener, so that only that one node gets updated on each mouse movement.

The other big alternative would be to implement the dragging logic in pure JS and have it emit events to .NET code only when the user releases the mouse with the node in a new location.

We do have a backlog item for drag-drop which may automate some of this in the future: #18754

@SteveSandersonMS SteveSandersonMS added the ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. label Oct 13, 2020
@ghost ghost added the Status: Resolved label Oct 13, 2020
@ghost
Copy link

ghost commented Oct 14, 2020

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@ghost ghost closed this as completed Oct 14, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Nov 13, 2020
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Status: Resolved
Projects
None yet
Development

No branches or pull requests

4 participants