appsmithorg / appsmith

Platform to build admin panels, internal tools, and dashboards. Integrates with 25+ databases and any API.
https://www.appsmith.com
Apache License 2.0
34.31k stars 3.71k forks source link

[Bug]: Delay in typing for property pane codeEditor due to main thread being busy #17215

Open rishabhrathod01 opened 2 years ago

rishabhrathod01 commented 2 years ago

Problem

Below demo & metrics were recorded on the application with 265 records in the table - https://release.app.appsmith.com/app/table-widget-slow/slow-filter-63366e4c10f2005612e63d46/edit

Demo showing delay in typing due to main thread being busy

https://user-images.githubusercontent.com/23132741/193206828-8d7d8621-9256-45db-b165-ae2700749f23.mov

Root cause of the delay

Main thread while typing took ~505 ms

Screenshot 2022-09-30 at 12 13 39 PM

The following tasks contributed to the delay

Screenshot 2022-09-30 at 12 34 20 PM

Both generateDataTreeWidget and getPropertiesUpdatedWidget has common getAllPathsFromPropertyConfigWithoutMemo method which took around 193 ms in both cases.

Possible solutions

While working on this please do consider creating a generic API that could be used to move expensive tasks to a new worker thread and how to maintain the code.

rishabhrathod01 commented 2 years ago

@aswathkk can you please check this issue once?
It seems performance has been impacted after this changes https://github.com/appsmithorg/appsmith/pull/16639/files#diff-7fb06bbc14bb619b1fe3f898559d585167462ee35e7705588a4978596e277052

aswathkk commented 1 year ago

Hi @Rishabh-Rathod, 
I tried reverting the change of childHasPanelConfig done in #16639. I did the profiling before reverting and after reverting. 
 
I didn’t notice any drastic change in the time taken to run the getAllPathsFromPropertyConfigWithoutMemo function.

 
 
I tried exploring some ways to optimise the usage of getAllPathsFromPropertyConfigWithoutMemo. But, didn’t succeed.

 I will just write my findings here: 
 
getAllPathsFromPropertyConfigWithoutMemo function iterates through all the properties (including the nested properties) and calculates the paths. For every property or every widget position updates, this function is getting called for all the widgets in the canvas. We are memoizing the function. But, still we are calling it multiple times with a lot of change in parameters.

Number of calls to this function increases as the number of widgets in the canvas increases. And the time taken to execute this function increases as the number of properties increases. 
Note: JSON form can have a lot of properties and nested properties depending on the incoming data.

 
 
In the example app shared by Rishab, the number of records in the table is not the cause for the perf issue, instead the number of columns in the table data which is fed to the JSON form is the issue.

Here's a solution that I propose to improve the performance of getAllPathsFromPropertyConfigWithoutMemo AFAIK, Not all the property updates cause a change in paths. So, these calls will mostly return the same path for each widget unless a property that has the potential to change a path is getting updated.
 Can we store all the paths for every widget globally? May be in the redux store and update these paths only when a path changing event happens? Then these expensive computations inside the function could be avoided.

bharath31 commented 1 year ago

@satbir121 @Rishabh-Rathod what is the next step here?

bharath31 commented 1 year ago

@Rishabh-Rathod could you please add the next steps here?

rishabhrathod01 commented 1 year ago

We will need to experiment with multiple approaches to understand what would be the best solution here

We could experiment with other solutions too.