Base solution for your next web application
Open Closed

Sluggish performance SPA #5257


User avatar
0
timmackey created

If I add a function to the DashboardComponent class:

console_log(index: number) {
        console.log('DashboardComponent console_log ' + index.toString());
    }

... and add ngClass to the first line of 'dashboard.component.html' like this:

<div [@routerTransition] id="TenantDashboard" [ngClass]="console_log(1)">

... I am able to observe in a browser debug console window that the page is being refreshed thousands of times per minute when there is no activity. Why is this happening? Is there a setting to limit page updates to refresh only if something changes?

I need to limit page updates because I have a large SPA with dozens of dynamically loaded child components, each of which has another half-dozen dynamically loaded child components. My system is becoming very sluggish. Task Manager reports CPU usage of 21% for the SPA, and I have many more components yet to be added. What techniques can I adopt to make my SPA robust? I want to avoid breaking my SPA into dozens of small SPAs to resolve performance issues. Current AspNetZero revision: 5.3


30 Answer(s)
  • User Avatar
    0
    aaron created
    Support Team
  • User Avatar
    0
    ismcagdas created
    Support Team

    @TimMackey do you see "CPU usage of 21%" even if you don't open the browser console ?

  • User Avatar
    0
    timmackey created

    Task Manager report with Swagger the only tab:

    Swagger tab and my SPA (The Test Machine), no 'console.log()' messages, F12 console window open:

    Swagger tab, my SPA (The Test Machine), no 'console.log()' message, No F12 debug window:

    I've managed to reduce the load somewhat by reducing the number of parameters passed to functions, but this is still a heavy burden. Data table filters implemented per PrimeNG example code are noticeably sluggish - 0.5 second for dropdown to appear, 1+ seconds to display filtered results. The previously reported 21% is with console logging.

    You can reproduce console logging to observe the problem as follows: Add 'helloFromAppComponent' code to app.component.html:

    <div class="m-grid__item m-grid__item--fluid m-wrapper" [ngClass]="helloFromAppComponent()">
                <router-outlet></router-outlet>
            </div>
    

    Add this function to app.component.ts:

    helloFromAppComponent() { console.log('hello from AppComponent'); }
    

    Open the browser debug window (F12). Observe 'hello from AppComponent' being logged at a high rate in the Console window. If there were a setting to slow the rate of update/refresh, and function invoke update on demand, that might resolve the issue. Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    If there were a setting to slow the rate of update/refresh, and function invoke update on demand, that might resolve the issue. Thank you.

    This is related to Angular's change detection actually. As far as I know it is not possible to configure something like that. You can try to upgrade to Angular v6, Angular-cli v6 and RxJs v6 to see if it makes any performance difference.

    Angular Team is making performance enhancements in every release. But updating to v6 of those libraries might not be easy. If you wantto uypgrade and face any problems, we can try to help.

  • User Avatar
    0
    chauey created

    I had also noticed yesterday Edge about 30% CPU just viewing a page with an empty table in it. Did not try in prod mode yet.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @chauey are you using AspNet Zero v5.5 ?

  • User Avatar
    0
    chauey created

    yes.

  • User Avatar
    0
    timmackey created

    I use PrimeNG Table/filter extensively in my app. I downloaded the PrimeNG demo from GitHub and ran it on my system. The resources in the image following are for PrimeNG Table Filter page (<a class="postlink" href="http://localhost:4211/#/table/filter">http://localhost:4211/#/table/filter</a>). What is PrimeNG doing (or not doing) that their demo app uses 0% CPU and is highly responsive? Below are resouces for ASP Net Zero's PhoneBookDemo, Dashboard page: The Administration pages have an even higher CPU usage than the Dashboard page! How is this possible? What is the ASP Net Zero framework doing that is causing high CPU usage?

    I think it is incumbent upon the ASP Net Zero development team to explain why their system consumes so much CPU resource (more than "is related to Angular's change detection"), why PrimeNG consumes 0% CPU resources, and, if you cannot release a global fix, what users need to do to mitigate CPU resource consumption. Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    I think it is incumbent upon the ASP Net Zero development team to explain why their system consumes so much CPU resource (more than "is related to Angular's change detection"), why PrimeNG consumes 0% CPU resources, and, if you cannot release a global fix, what users need to do to mitigate CPU resource consumption. Thank you.

    @TimMackey the thing is, we don't see this behaviour on our environments. We are hosting Angular v6 (was hosting Angular v5 before that) for our official demo and our server's use most of the time less than %10 CPU. Our demo application is used by many visitors each day.

    Have you tried to publish your app and see if has the same behaviour ?

    By the way, PrimeNG uses client side data as far as I know on their samples and AspNet Zero uses many other client side libraries. I think comparing AspNet Zero with PrimeNG's demo cannot help us to understand this problem.

  • User Avatar
    0
    timmackey created

    @ismcagdas My SPA has 15 defined components, hierarchically rendered to 23 views, 3 levels deep. Add more levels for the PrimeNG components, and it could easily reach 5 or 6 levels deep. Below is a screenshot of a small section of my SPA. I have 14 of those colored blocks so far, each of which is a dynamically loaded component. The grid within each block is dynamically loaded. The buttons in the grids are dynamically loaded. The progress bar is dynamically loaded. I have more nested levels of dynamically loaded components planned to be implemented. !_(http://i64.tinypic.com/avlu7m.png) Here is a link on how dynamic components work in Angular: [https://angular.io/guide/dynamic-component-loader])

    PrimeNG uses client side data

    I modified PrimeNG 'tablefilterdemo' page using the same technique I described in my June 19 post. The console message appears 8 times per page refresh. If there is no user-initiated activity, there are no further console messages. Hence, 0% CPU reported by Task Manager.

    we don't see this behaviour on our environments

    our server's use most of the time less than %10 CPU

    This is not surprising. Your Dashboard page is VERY SIMPLISTIC. It has no hierarchically arranged views. Read this: [https://angular.io/guide/architecture-components#templates-and-views]) to unlock the full power of Angular.

    Had you created an SPA with multiple levels of multiple components you might come to the conclusion that your current implementation is problematic. Why would [i:2gnivnva]any_ CPU be consumed when there is no user-initiated processing and the cursor is not moving?

    One of the great features of Angular is that it is asynchronous. Net Zero seems to have added a polling loop, which is killing performance for anything more sophisticated than the most simplistic SPA.

    With Fiddler I monitored communication with the server. The only time communication occurs is during page load, to load a few images. Then nothing. My app has no timers. Even though the cursor is not moving, my implementation of hierarchically arranged views are (needlessly) updated dozens of times per second on your polling loop. My conclusion is that sluggish performance has nothing to do with server communication.

    If you add the code to the NetZero app per my June 19 post to reproduce the log message, i.e.

    helloFromAppComponent() { console.log('hello from AppComponent'); }
    

    ...you will observe that the log message is displayed at a high rate continuously. You can add a console.log message to any of your components and get similar results. I believe that it is this continuously running thread that is causing needless CPU consumption. Why is this thread being run continuously, and not just a few times when the page loads? What do I need to change to stop this thread from running continuously? I would like a definitive answer to these two questions, please. And when you reply, would you please confirm that you have observed the log message in your own testing? Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I have created an issue here <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/issues/1333">https://github.com/aspnetzero/aspnet-ze ... ssues/1333</a>. I also tried your initial suggestion and it really increased the CPU usage to %25 when the browser console is open. But when I close the browser console (Google Chrome) CPU usage goes down to %2-%3.

    We will investigate this problem on the issue above I have mentioned, please follow the issue to get updated.

  • User Avatar
    0
    timmackey created

    Thank you for creating a Github issue and committing to resolving this problem.

    Please be cognizant that while you are seeing only 2% to 3% CPU usage it is because ASP.NET Zero's Dashboard is displaying a single component/view, and not a hierarchy of views of dynamically loaded components. It is the presentation of dozens of views on the same SPA which is causing high CPU usage in the existing polled environment. A correctly created Angular app should use 0% CPU in its quiescent state.

  • User Avatar
    0
    ismcagdas created
    Support Team

    We will be releasing v5.5.1 as a bugfix release. v5.5.1 contains mostly UI related fixes (css stuff). Then we will work on this issue as a high priority.

    Probably v5.5.1 will be released today or tomorrow.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @TimMackey,

    Could you check if the applied solution works for you ?

  • User Avatar
    0
    timmackey created

    This DOES NOT fix the problem. You can verify for yourself if the problem is fixed by doing the following in the PhoneBookDemo app:

    1. Add this code to the end of the file 'app.component.html':
    <div [ngClass]="helloFromAppComponent()"></div>
    
    1. Add this code to the 'app.component.ts' file between the constructor() and ngOnInit():
    count = 1;
        helloFromAppComponent() { this.count = this.count + 1; console.log('hello from AppComponent ' + this.count); }
    
    1. Run the program. Open the debugger console (F11) in your browser. If you see "hello from AppComponent 123" with the number constantly increasing, then the problem is NOT resolved. (Tested with PhoneBookDemo that was downloaded on 1 April 2018.)
  • User Avatar
    0
    ismcagdas created
    Support Team

    @TimMackey I have tested this on the dev branch of AspNet Zero but I will test it again by downloading the v5.5.2 on aspnetzero.com again and let you know the result.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @TimMackey,

    You are right. It seems like SignalR is also triggering change detection frequently but it happens 10 secs at first and then 15 secs period after that. At least it was like that according to my tests.

    Instead of logging a number, I have logged "console.log(new Date())".

    I have fixed it in below commit, could you also try that in your project ? I assume you have already implemented the first commit in the related issue.

    <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/commit/e535576934c3b10a85be8ae8d19ad46d5b229bbb">https://github.com/aspnetzero/aspnet-ze ... 6d5b229bbb</a>

  • User Avatar
    0
    timmackey created

    @ismcagdas -

    I implemented the first set of changes in PhoneBookDemo. I am unable to implement the second set of changes because you are changing 'aspnet-zero-core', and 'aspnet-zero-core' is significantly different from what I am using as a test bed: 'aspnet-zero-samples/PhoneBook-Angular', as reported since the beginning of this thread.

    I don't know how this issue gets resolved without both of us using the same code base and inserting the test code in the same locations in .htm and .ts files.

    I hesitate to merge the current release with my code (v5.3) since it is a full day ordeal. I would prefer to perform a merge after a solution has been verified and released.

    To better illustrate the problem, I am logging...

    showtime() {
            let time = new Date();
            console.log(time.getMinutes() + ':' + time.getSeconds() + '.' + time.getMilliseconds() );
        }
    

    Here is a screen shot of my results: These results are consistent with what I see in my application.

    @ASP.Net Zero Community:

    Would you have 10 minutes to assist in finding a resolution to this issue? If yes, would you please drop in a few lines of code to the prescribed locations into your app and report the results (and your release version) in this thread?

    Add this code as the last line in 'app.component.html':

    <div [ngClass]="showtime()"></div>
    

    Add this code after the constructor in 'app.component.ts':

    showtime() {
            let time = new Date();
            console.log(time.getMinutes() + ':' + time.getSeconds() + '.' + time.getMilliseconds() );
        }
    

    Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @TimMackey,

    'aspnet-zero-samples/PhoneBook-Angular' sample is on an old version of AspNet Zero. Also is that your real project ? It shouldn't be your real life project because it is a sample.

    Opening a SignalR connection to server inside the angular zone is one of the things causing this problem. So my second commit fixes this issue as well.

    If you can send your project via email to <a href="mailto:[email protected]">[email protected]</a> I will implement the changes for you.

    Thanks

  • User Avatar
    0
    timmackey created

    @ismcagdas,

    I downloaded ASP.NET CORE & Angular, version 5.5.2 , ASP.NET Core 2.1 (please refer my download log) and merged changes f9acc0a and e535576. I did NOT merge my development code.

    I observed the console.log messages during cursor movement, scrolling, and window resize, but not when there is no movement. This is an improvement. However, when moving the cursor quickly, the CPU usage shot up to 30%. Moving the cursor caused the log messages to continue at greater than 16 per second for another 4 seconds after the cursor stopped moving.

    This behavior is not present in the PrimeNg Master code (which is available for download). Resizing, scrolling, and cursor movement do not cause any log messages, and the CPU load is minimal - cursor movement never exceeded 5% CPU usage.

    When an app has multiple levels of nested views (like my app) and a text input control is used, there is a 1-2 second delay between clicking a key and the character showing up on screen. This is not acceptable UX.

    While the latest change represents an improvement, I don't think this issue is fully resolved. Why is it required that there must be hundreds of log messages (and CPU load) for simply moving the cursor?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @TimMackey,

    I'm glad that we are seeing the same behavior now :). I haven't tried resizing, scrolling, and moving the cursor before but when I try now now I can see it does what you say.

    Probably Metronic is executing some code while doing these actions on the UI which is causing change detection on Angular. I have reopened the issue and will work on that and let you know if we can do anything about it.

  • User Avatar
    0
    timmackey created

    Hi @ismcagdas, Would you please post a status update on this issue? Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @TimMackey,

    Sorry, I thought you have subscribed to the related issue <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/issues/1333">https://github.com/aspnetzero/aspnet-ze ... ssues/1333</a>. I have made several enhancements on this PR <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/commit/b11f7ad3cb8f90f0ae9aaebac855819951dbbc38">https://github.com/aspnetzero/aspnet-ze ... 9951dbbc38</a>.

    Basically blockUI and malihu-custom-scrollbar-plugin plugins were causing change detection when clicked on document (mouseup event actually) or moving curson on document. We have fixed those problems.

    Currently there will be change detection when you move cursor on the left menu which is caused by Metronic's way of handling left menu animations. We don't want to interfere with Metronic's source code and we left it like that at the moment.

  • User Avatar
    0
    timmackey created

    Hi @ismcagdas,

    I added the latest changes. This is an improvement. I note the dashboard panels with charts cause events. Panels without charts do not cause events. What is the target date for v5.6 release?

    Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @TimMackey,

    Yes, I forgot to mention the dashboard. The charts are rendered every time when the mouse move or window resizes. You can disable the windows resize event on dashboard component. We used this because of a problem in charts. If we don't render charts, it will have a bad look when window resizes.

    We are hoping to release v5.6 this week, maybe Friday.

  • User Avatar
    0
    timmackey created

    @ismcagdas,

    I merged with my project with Ver 5.6. The performance is still unacceptably sluggish.

    I will send my project to <a href="mailto:[email protected]">[email protected]</a> so that you can observe the performance first-hand, and hopefully diagnose the problem and devise a solution.

    Thank you.

  • User Avatar
    0
    timmackey created

    @ismcagdas,

    I discovered 16 instances of

    @HostListener('window:resize', ['$event'])
        onResize(event?) { ... }
    

    being created in my code. Modifying my code for a single instance has markedly improved performance. Please keep the changes for Version 5.6.0 related to this issue.

    This issue can be closed. Thank you.

  • User Avatar
    0
    ismcagdas created
    Support Team

    @TimMackey, thank you for letting us know, I couldn't identify the problem. Could you share your modification to source code ? We can implement the same in AspNet Zero.

  • User Avatar
    0
    timmackey created

    The problem was in my code. Sorry for the initial post not making that clear. I have edited the original post to clarify the source of the error was mine.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Thanks :)