Extreme performance degradation when adding handler for RowSelected event

Please consider the attached example - This is based on Syncfusion Blazor  18.1.0.55

I am populating the grid with 500 very simple records. This works perfectly in /fast

Selecting a row seems instant and all is great.

However, when I add an event handler using:

<GridEvents RowSelected="@rowSelected" TValue="Order" />

with a practically emty backend implementation:

    public void rowSelected(Syncfusion.Blazor.Grids.RowSelectEventArgs<Order> args)
    {
        Console.WriteLine($"Row selected: {args.Data.Key}");

        //Does absolutely nothing that takes time...
    }


All of a sudden the grid feels very sluggish and it takes roughly 3 seconds for the row to become selected.

I would really like to avoid enabling virtualization as it appears to be very buggy (e.g. in our full app when scrolling I keep seeing the same records etc. and I won't be needing more than roughly 500 rows anyway, which seems to be working fine) - If needed I'il create a separate post for that.

For now I suppose this enormous difference in performance, when doing practically nothing yet (all I want is to know when a row is selected + which one), seems to be a bug.

If I may give a suggestion - It came to my attention that the Selected event creates a completely new c# instance of the underlying object - I was expecting a reference and needed to implement some Equals logic in order to identify the selected item in my list of data. I guess this is because of technical reasons regaring the JS/Interop layers - but since it is possible to provide a key column - may I suggest that of using TValue stuff everywhere - simply the IsPrimaryKey field value is returned in stead of a complete (deserialized) copy of the original record?

Could you please provide any assistance?

Thanks in advance!

Attachment: tests_1c2123bb.zip

19 Replies

RI richardv June 4, 2020 02:40 PM UTC

Added info: try for instance navigating between rows using the up and down arrow keys in the /fast vs /slow pages and it should be very apparent what I mean.


RI richardv June 5, 2020 08:06 AM UTC

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                var t = new System.Timers.Timer(100);
                t.Elapsed += (s, e) => 
                {
                    test();
                };
                t.Start();
            }
        }

        private async void test()
        {
            var s = await _grid.GetSelectedRowIndexes();
            Console.WriteLine($"Selected: {JsonConvert.SerializeObject(s)}");
        }

as a temporary work around I have done this in my component to be able to simulate an event. Obviously this shouldn't be used like this forever but it is very effective in keeping things fast and still getting a notification on the c# end. 

Perhaps someone facing similar issues can use this this temporary fix so I'm posting it here.


RS Renjith Singh Rajendran Syncfusion Team June 8, 2020 02:32 PM UTC

Hi Richard, 

Greetings from Syncfusion support. 

Since the Blazor WebAssembly does run the .NET code on an interpreter, normally blazor wasm is 20x slower than blazor server side. So, the default selection in server side takes 100ms then it will take 2s in wasm.  

Please refer the general link below, 

So we suggest you to use the workaround to overcome this default wasm behavior. And we will improve virtualization feature in our upcoming Volume 2, 2020 release. 

Please get back to us if you need further assistance. 

Regards, 
Renjith Singh Rajendran 



RI richardv replied to Renjith Singh Rajendran June 10, 2020 08:54 AM UTC

Hi Richard, 

Greetings from Syncfusion support. 

Since the Blazor WebAssembly does run the .NET code on an interpreter, normally blazor wasm is 20x slower than blazor server side. So, the default selection in server side takes 100ms then it will take 2s in wasm.  

Please refer the general link below, 

So we suggest you to use the workaround to overcome this default wasm behavior. And we will improve virtualization feature in our upcoming Volume 2, 2020 release. 

Please get back to us if you need further assistance. 

Regards, 
Renjith Singh Rajendran 


Thank you for your reply.

I have to admit being very disappointed this issue will not be addressed. To me it is a clear sign of a bug.

Setting an event handler for a trivial event, -not even implementing the eventhandler to do anything meaningful- makes this component practically unusable.

It seems to me that a lot of cascading side-effects regarding loads of unneeded round-trips through JS-Interop are happening simply by setting that event-handler causing all sorts of trouble. You are stating that the normal behavior for setting an event handler for the on-selected in the best case (native) scenario is 100ms - are you serious? That is totally unacceptable.

It is true blazor wasm is a lot slower, possibly 20x slower, than native. But accepting something takes 100ms when in fact this should take less than 1ms seems to be a wrong starting point.

When waiting for a reply I created a proof of concept Blazor wrapper for the open source Tabulator grid library. I achieved all functionality I need and regarding the enormous performance increase I have been able to achieve compared to SF-grid, in combination with SF's seemingly unwillingness to address this issue, has led me to decide to not build upon the SF grid for our application.

Since the SF grid was a major reason we were going to settle on SF as component library we are forced to re-evaluate that decision as well since it is for us not yet "too late" in the development process. 


VN Vignesh Natarajan Syncfusion Team June 11, 2020 04:46 PM UTC

Hi Richard, 

We understand your frustrations.  

Query: “It seems to me that a lot of cascading side-effects regarding loads of unneeded round-trips through JS-Interop are happening simply by setting that event-handler causing all sorts of trouble 

We can accept your comments that introduction of RowSelected event causes 3 second delay while selecting a record in Blazor webassembly project. But it is not definitely due to JSInterop call made during the eventCallback function.  

During a call back function(in your case EventCallBack<object> RowSelected), component’s StateHasChanged will be triggered for the components and its sub components to apply changes. In DataGrid, we have rendered each cell in a row as individual component. So you have 500 records and 2 columns, then statehaschanged has to called for every components (say 500*2 = 1000 times) before completing the requested action with an event call back. Hence the time delay occur in webassembly project during a event call back function. So the reported issue is not due to JSInterop call.  

As a workaround we can overcome the reported issue by override the ShouldRender lifecycle event of Blazor. Refer the below code example.  

private bool shouldRender; 
 
   protected override bool ShouldRender() => shouldRender; 
 
   List<Order> _orders = Enumerable.Range(0, 500).Select(x => new Order() { Key = $"Key {x}", Name = $"Order name {x}" }).ToList(); 
 
   public void rowSelected(Syncfusion.Blazor.Grids.RowSelectEventArgs<Order> args) 
   { 
       shouldRender = false; 
       Console.WriteLine($"Row selected: {args.Data.Key}"); 
 
       //Does absolutely nothing that takes time... 
   } 


Kindly download the modified sample from below  


Please get back to us if you have further queries.  

Regards, 
Vignesh Natarajan  



CW Christian Weyer replied to Vignesh Natarajan February 19, 2021 08:40 AM UTC

Hi Richard, 

We understand your frustrations.  

Query: “It seems to me that a lot of cascading side-effects regarding loads of unneeded round-trips through JS-Interop are happening simply by setting that event-handler causing all sorts of trouble 

We can accept your comments that introduction of RowSelected event causes 3 second delay while selecting a record in Blazor webassembly project. But it is not definitely due to JSInterop call made during the eventCallback function.  

During a call back function(in your case EventCallBack<object> RowSelected), component’s StateHasChanged will be triggered for the components and its sub components to apply changes. In DataGrid, we have rendered each cell in a row as individual component. So you have 500 records and 2 columns, then statehaschanged has to called for every components (say 500*2 = 1000 times) before completing the requested action with an event call back. Hence the time delay occur in webassembly project during a event call back function. So the reported issue is not due to JSInterop call.  

As a workaround we can overcome the reported issue by override the ShouldRender lifecycle event of Blazor. Refer the below code example.  

private bool shouldRender; 
 
   protected override bool ShouldRender() => shouldRender; 
 
   List<Order> _orders = Enumerable.Range(0, 500).Select(x => new Order() { Key = $"Key {x}", Name = $"Order name {x}" }).ToList(); 
 
   public void rowSelected(Syncfusion.Blazor.Grids.RowSelectEventArgs<Order> args) 
   { 
       shouldRender = false; 
       Console.WriteLine($"Row selected: {args.Data.Key}"); 
 
       //Does absolutely nothing that takes time... 
   } 


Kindly download the modified sample from below  


Please get back to us if you have further queries.  

Regards, 
Vignesh Natarajan  


Hi Vignesh,

this is indeed an excellent analysis - and a clear description of how Blazor works. Thanks for that!

Did you guys in the meantime change anything in your Grid implementation to make this easier to use for better performance?

Thanks and best regards,
-Christian


RS Renjith Singh Rajendran Syncfusion Team February 22, 2021 06:15 AM UTC

Hi Christian, 

Greetings from Syncfusion support. 

We have improved the Grid performance in our latest Syncfusion version releases. Now you can use the PreventRender method to control the Grid rendering based on your requirements. 
 
Please refer the below documentation for more details regarding this, 
 
Please get back to us if you need further assistance. 

Regards, 
Renjith Singh Rajendran 



CW Christian Weyer February 23, 2021 06:14 PM UTC

Thank you!


RS Renjith Singh Rajendran Syncfusion Team February 24, 2021 05:09 AM UTC

Hi Christian, 

Thanks for your update. Please get back to us if you need further assistance. 

Regards, 
Renjith R 



CW Christian Weyer replied to Renjith Singh Rajendran March 19, 2021 03:43 PM UTC

Hi Christian, 

Thanks for your update. Please get back to us if you need further assistance. 

Regards, 
Renjith R 


Me again :-) Can you share the code on how the PreventRender() is implemented?
Thanks!


RS Renjith Singh Rajendran Syncfusion Team March 22, 2021 12:35 PM UTC

Hi Christian, 

Based on argument passed in this method(PreventRender(false) or PreventRender(true)), we will prevent/allow the component rendering internally when calling this method.  

And also, we have Source Code Add-on installer. Please refer the below documentation for more details on this, 

Please get back to us if you need further assistance. 

Regards, 
Renjith R 



CW Christian Weyer March 22, 2021 08:31 PM UTC

Thanks a lot!


RS Renjith Singh Rajendran Syncfusion Team March 23, 2021 06:52 AM UTC

Hi Christian, 

Thanks for your update. Please get back to us if you need further assistance. 

Regards, 
Renjith R 



MA Matej June 11, 2021 05:56 AM UTC

Many thanks,

Well it works great.

Best Regards
Matej H.


RS Renjith Singh Rajendran Syncfusion Team June 14, 2021 04:47 AM UTC

Hi Matej, 

Thanks for your update. Please get back to us if you need further assistance. 

Regards, 
Renjith R 



TJ Tom Johnes February 19, 2022 05:39 AM UTC

Extreme performance degradation when adding handler for RowSelect event...

I have a very small grid with less then 100 rows and 5 columns.

Working with such a slow grid is very annoying even you navigate with up and down arrow keys !

Do you expect any improvement in the very near future ?

Thank You !

This is my code for the RowSelect Event that tells me the current selected row and the number of grid's total rows :

    private async Task RowSelectHandler(RowSelectEventArgs<MYCartModel> args)

    {

        var_grid_row_is_selected = true;

        var RowIndexes_Object = await this.MYCART_GRID.GetSelectedRowIndexes();

        var RowIndexes_Array_TMP = Convert.ToInt32(RowIndexes_Object.ToArray().GetValue(0)) + 1;

        var_current_selected_record = Convert.ToInt32(RowIndexes_Object.ToArray().GetValue(0)) + 1;


        var FilteredRecords_Object = await this.MYCART_GRID.GetFilteredRecords();

        var_total_mycart_records = JsonConvert.DeserializeObject<List<object>>(JsonConvert.SerializeObject(FilteredRecords_Object)).Count();

        if (var_current_selected_record>0 && var_total_mycart_records > 0)

        { var_grid_row_counter_text = var_current_selected_record.ToString() +'/' + var_total_mycart_records.ToString(); }


        else if (var_current_selected_record == 0 && var_total_mycart_records > 0)

        { var_grid_row_counter_text = var_total_mycart_records.ToString(); }


        else if (var_current_selected_record == 0 && var_total_mycart_records == 0)

        { var_grid_row_counter_text = ""; }


}



RS Renjith Singh Rajendran Syncfusion Team February 21, 2022 03:31 PM UTC

Hi Tom, 
 
We have documented the topic to improve performance in grid when using wasm application. We suggest you to refer to the below documentation for more details on this topic, 
 
And also, it is a must to enable Paging or Virtualization features in Grid to improve performance. We have documented this in our online documentation, please refer the link below for more details, 
 
Please refer the above documentations and check this from your side. If you are still facing difficulties then kindly share with us a simple issue reproducing sample along with a video demo for us to validate based on this scenario. Please get back to us if you need further assistance. 
 
Regards, 
Renjith R 



AP Andre Putz June 7, 2023 01:42 PM UTC

Helo everybody,


I used the  PreventRender and it's not helped too much, let I say without this functionality it's takes 3s to update a cell (UpdateCellAsync) and using the PreventRender, I had 2.8s, so is not a great thing at the end of the day. 


So I believe that Syncfusion needs to continue the performance's improvements to reach a better results with Blazor WebAssembly 





MS Monisha Saravanan Syncfusion Team June 8, 2023 09:18 AM UTC

Hi Andre,


We have prepared an simple sample based on your shared reference. But it is taking just 8 to 9 milliseconds to update an cell using UpdateCellAsync. We have printed the milli seconds taken in the browser console. Kindly make a look in to it and revert us the way you have performed calculation.


If possible kindly share us an simple issue reproduceable sample or modify the reported issue on the below mentioned sample and also kindly share us the entire Grid code snippet with video demonstration. It will be very helpful for us to validate the reported issue.


Please let us know if you have any concerns.


Regards,

Monisha


Attachment: MyGrids_ae0d480d.zip

Loader.
Up arrow icon