NeutroniumCore / Neutronium

🚀 Build .NET desktop applications using HTML, CSS and javascript.
https://neutroniumcore.github.io/Neutronium/
MIT License
1.35k stars 121 forks source link

Freeze on vue SPA application #134

Open jmecosta opened 4 years ago

jmecosta commented 4 years ago

hi,

ive migrate our app to vue SPA template and mostly everything works great except for a small annoying problem that everyone is complaining...

We have a data table with 2000 entries (10 columns of data), reading the data takes ms. However when pushing all the data into a observable collection the UI locks for a few seconds and sometimes it never recovers.. the workaround we found is to kill ChromiumFxRenderProcess.exe which forces the ui to render. However sometimes some users describe that doesnt work always and they have sometimes a white screen after killing.

This is not easy to reproduce, but the larger the dataset is in the data table the higher seems the chance of friezes

@David-Desmaisons have u ever experienced this behaviour and ways of reducing the likelyhood of occuring in production

thanks in advanced jorge costa

David-Desmaisons commented 4 years ago

Use ObservableCollection AddRange to batch all the changes, this should result in a performance boost.

jmecosta commented 4 years ago

hum, can try. but also people observe crashs that i have just experienced also image

some ideas about this?

jmecosta commented 4 years ago

and i must be missing something really obvious hovever the addrange extensions doesnt work with observablecollections image

David-Desmaisons commented 4 years ago

hum, can try.

You definitivelly should try. The performance improvemnt should be very important if you are adding the 2000 items at once.

Regarding the stack you are sharing, this probably the consequence of ahving chromium being unresponsive due to heavy CPU computation.

David-Desmaisons commented 4 years ago

Check https://github.com/NeutroniumCore/Neutronium/blob/master/Tests/UniversalTests/HTMLBindingTests/Helper/ObservableRangeCollection.cs

jmecosta commented 4 years ago

ok that works nicely! add to move all those background tasks but seems the overall result is a much more responsive start. thanks for the hint.

jmecosta commented 4 years ago

hum! some side effect.... running the addrange works ok in constructuror. however if pushing refresh button results in a single element added in table. The addrange however doesnt seem to be the issue since the collection contains the full 2000 elments

image

image

do i need do so somthing to get the table showing the complete list

and the model in the view seems that it only has one. image

so something weird with sending the collection to the view

David-Desmaisons commented 4 years ago

To improve performance:

1) Create ViewModel as small as possible: -public property should only be the ones needed to be displayed in the UI -use internal or bindable false attribute for other properties if needed 2) Make your ViewModel readonly (no getter for property) whenever possible=> Neutronium will not create observers on the js side that will reduce the memory consumpution. 3) Batch changes on array with range updates

jmecosta commented 4 years ago

yep, thanks. the application is very performant.. the only thing thats is a bit slow and causing issues is the data table that i cant really remove data.

of course i could move all the logic to the c# side.. but the vuetify datable is super fast filtering stuff when the data reaches the view. so would be cool to keep it.

jmecosta commented 4 years ago

@David-Desmaisons 1.5.2 fixes the issue with addrange, ive figure it out since there was already open ticket about the problem. however the application is still not reliable!

however the locks dont seem to be solved! i think i am using all the recomended perf tips above:

        private async Task ReadCasesFromDisk(string tafCasesBasePath, bool force)
        {
            if (string.IsNullOrEmpty(GitService.GetCurrentTafDevBasePath()))
            {
                return;
            }

            messageLogger.PublishMessage("Loading Cases... Please Wait");
            this.FtcsCasesFiltered.Clear();
            this.cachedTestCases.Clear();
            this.TableLoading = true;
            this.Running = true;

            ICollection<TestCase> casesFromDisk = 
                await Task.Run(() =>
                {
                    return CaseDbService.GetCasesFromDisk(tafCasesBasePath, this.messageLogger, this.ActionOnSelectCaseChanged, force);
                });

            messageLogger.PublishMessage($"Loaded {casesFromDisk.Count} from Disk");
            // normal list, private
            this.cachedTestCases.AddRange(casesFromDisk);

            // observable range collection, casesFromDisk > 2k elements
            this.FtcsCasesFiltered.AddRange(casesFromDisk);
            this.TableLoading = false;
            this.Running = false;

            messageLogger.PublishMessage($"Ui Updated {casesFromDisk.Count}");
        }

Loading the data from disk is not a issue, its mostly the chromium renderer that struggles with so much data!

29/03/2020 14:52:46 : Ui Updated 2089
29/03/2020 14:52:46 : Loaded 2089 from Disk
29/03/2020 14:52:46 : Loading Cases... Please Wait
29/03/2020 14:52:25 : Ui Updated 2089
29/03/2020 14:52:25 : Loaded 2089 from Disk

So the ui locks, and only after killing the render process the ui gets back! Some intersting obeservations, if i try to record with showmore for example i cant reproduce the issue! You havent observe this beavhiour earlier?

David-Desmaisons commented 4 years ago

if i try to record with showmore What do you mean?

jmecosta commented 4 years ago

ok manage to take a recording with showmore showing the issue:

see video inside zip. 20200329_232420.zip

this is the crash:

>   mscorlib.dll!System.ThrowHelper.ThrowKeyNotFoundException() Unknown
    mscorlib.dll!System.Collections.Generic.Dictionary<int, System.__Canon>.this[int].get(int key)  Unknown
    ChromiumFX.dll!Chromium.Remote.RemoteConnection.ReadLoop()  Unknown
    ChromiumFX.dll!Chromium.Remote.RemoteConnection.ReadLoopEntry() Unknown
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()    Unknown
David-Desmaisons commented 4 years ago

I will relase a new version shortly. Please try to reproduce with the new version.