Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Performance issues using ReactGrid. #92

Closed

Description

@pauldotknopf

When running the "ReactGrid" sample project, I get page load times of ~1s. Is this expected? There are no network calls, apart from the call to node.exe for the markup, so I am curious where this bottleneck is.

If I remove the aspnet-prerender-* from /Views/Home/Index.cshtml, the page load time drops to 3ms.

I don't think this example project should have a page load time above 100ms, maybe less. What are your thoughts on this?

Activity

  1. laskoviymishka commented on May 24, 2016

    @laskoviymishka
    Contributor

    Hi, this really looks like issue related to RC2 migration.

    UPD:
    this issue also reproduce on template (both ng2 and react). Root couse somewhere inside HttpNodeHostingModel

  2. laskoviymishka commented on May 24, 2016

    @laskoviymishka
    Contributor

    @pauldotknopf You may try change HostingModel (it little buggy right now and don't work with ng2, but with react should be fine). It can be done with following code:

                services.AddNodeServices(new NodeServicesOptions
                {
                    HostingModel = NodeHostingModel.InputOutputStream
                });
    
  3. pauldotknopf commented on May 24, 2016

    @pauldotknopf
    ContributorAuthor

    This brings the response time down to ~30ms, which is A LOT better.

    What should be the expected response time for HTTP?

  4. laskoviymishka commented on May 24, 2016

    @laskoviymishka
    Contributor

    @pauldotknopf this option much simplier 😄

    Well this is more like issue with HttpClient.PostAsync itself. I was able to find line which is stack for 1 second:

    var response = await client.PostAsync("http://localhost:" + _portNumber, payload);
    

    Just to make sure i ran very same request with PostMan, and this request elapsed ~50-70 ms. Then i isolate this line of code in separate console project, and confirm that it still require 1-1.5 second (but stopwatch show different).

    THIS IS REALLY STRANGE!

    becouse i run simple test app and with legacy .net and .net core for http Client (really same code).

  5. pauldotknopf commented on May 24, 2016

    @pauldotknopf
    ContributorAuthor

    So, should we file a bug with the .NET team?

  6. laskoviymishka commented on May 24, 2016

    @laskoviymishka
    Contributor

    i still working on it 😅
    when i be sure root couse i have to file a bug in right repository.

  7. laskoviymishka commented on May 24, 2016

    @laskoviymishka
    Contributor

    @pauldotknopf could you please try to run this sample repo https://github.com/laskoviymishka/HttpIssue to run it made followin:

    1. Clone repository
    2. Run cd src\WebApplication1 & dotnet restore & dotnet run
    3. Run cd ..\ConsoleApp1\ & dotnet restore & dotnet run
    4. Check how long it takes to make 20 post api requests

    To see how it works in classic .net open solution
    There is 2 console project with really same code, but .netcore version take significant longer

  8. pauldotknopf commented on May 27, 2016

    @pauldotknopf
    ContributorAuthor

    UPDATE: This output is wrong, there was a bug in demo app. Check the next comment.

    ConsoleApp1 output:

    Elapsed=726 ms
    Elapsed=45 ms
    Elapsed=43 ms
    Elapsed=15 ms
    Elapsed=16 ms
    Elapsed=13 ms
    Elapsed=14 ms
    Elapsed=13 ms
    Elapsed=5 ms
    Elapsed=5 ms
    Elapsed=6 ms
    Elapsed=12 ms
    Elapsed=31 ms
    Elapsed=9 ms
    Elapsed=10 ms
    Elapsed=11 ms
    Elapsed=16 ms
    Elapsed=15 ms
    Elapsed=7 ms
    Elapsed=8 ms
    Total Elapsed=63 ms
    

    ConsoleApplication1 output:

    Elapsed=51 ms
    Elapsed=2 ms
    Elapsed=2 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Elapsed=5 ms
    Elapsed=1 ms
    Elapsed=1 ms
    Total Elapsed=90 ms
    
  9. pauldotknopf commented on May 27, 2016

    @pauldotknopf
    ContributorAuthor

    Update, there was a bug in your demo repository. Replace Milliseconds with TotalMilliseconds. Otherwise, you only see the milliseconds within the current second.

    Here is the new output, which clearly illustrates a HUGE issue with .NET Core.

    ConsoleApp1 output:

    Elapsed=1246.4032 ms
    Elapsed=1032.1824 ms
    Elapsed=1031.5464 ms
    Elapsed=1032.7355 ms
    Elapsed=1013.7454 ms
    Elapsed=1010.2167 ms
    Elapsed=1012.8409 ms
    Elapsed=1007.1485 ms
    Elapsed=1011.054 ms
    Elapsed=1011.5348 ms
    Elapsed=1005.3291 ms
    Elapsed=1003.5637 ms
    Elapsed=1021.1278 ms
    Elapsed=1006.7902 ms
    Elapsed=1005.657 ms
    Elapsed=1010.9605 ms
    Elapsed=1012.1959 ms
    Elapsed=1012.4846 ms
    Elapsed=1011.1206 ms
    Elapsed=1009.1076 ms
    Total Elapsed=20558.7293 ms
    

    ConsoleApplication1 output:

    Elapsed=1152.2902 ms
    Elapsed=8.5079 ms
    Elapsed=9.1006 ms
    Elapsed=7.3624 ms
    Elapsed=10.3489 ms
    Elapsed=8.9677 ms
    Elapsed=9.6616 ms
    Elapsed=9.1713 ms
    Elapsed=7.9744 ms
    Elapsed=5.5812 ms
    Elapsed=6.3373 ms
    Elapsed=5.522 ms
    Elapsed=4.5986 ms
    Elapsed=3.1634 ms
    Elapsed=7.9505 ms
    Elapsed=2.7354 ms
    Elapsed=2.2976 ms
    Elapsed=2.4869 ms
    Elapsed=3.334 ms
    Elapsed=2.0512 ms
    Total Elapsed=1276.8956 ms
    

    THIS IS A HUGE ISSUE - 20 seconds vs 1 second.

  10. laskoviymishka commented on May 27, 2016

    @laskoviymishka
    Contributor

    @pauldotknopf thx for catch! I fixed my repo. Let address this to core fx team.

  11. SteveSandersonMS commented on Jun 1, 2016

    @SteveSandersonMS
    Member

    Fixed with 50ee405. Also, you could now use the new Stream transport which is faster and doesn't have a similar issue.

  12. naveedahmed1 commented on Sep 29, 2017

    @naveedahmed1

    I am having the same performance issue with my Angular 4 app. The initial load time seems slow 1-2 sec sometimes even 3 seconds. I tried adding below to my startup file:

     services.AddNodeServices(new NodeServicesOptions
                {
                    HostingModel = NodeHostingModel.InputOutputStream
                });
    

    But it seems that it no longer works with .net core 2.0. Any guidance would be highly appreciated.

  13. SteveSandersonMS commented on Sep 29, 2017

    @SteveSandersonMS
    Member

    @naveedahmed1 After we fixed some issues in the HTTP transport, it was equally fast as InputOutputStream, so there was no benefit to using InputOutputStream any more. That's why it never shipped in the final version, and you wouldn't get any perf improvement from using it even if it did.

    If you are able to track down your perf issue to something specific in the code in this repo, please let us know how to reproduce the issue so we could investigate.

    The initial load time

    If by that you mean "first HTTP request after app startup" then that's to be expected - it does take a couple of seconds to start up the Node instance to do the prerendering. Subsequent requests should be far faster though. If all subsequent requests are slow too, that suggests an issue in your code (but again, if you track it down and think it's an issue in the JavaScriptServices code, please let us know the details).

  14. naveedahmed1 commented on Sep 29, 2017

    @naveedahmed1

    Thank you so much @SteveSandersonMS for your quick reply and explaining this. The delay in first request after app startup makes sense. Can you please also share if the same Node instance is used for all subsequent server side rendered requests? I am seeing delay for static portion of my app as well (which is not making any http call).

    I have services.AddNodeServices(); in my startup file and using the below code from this repo https://github.com/MarkPieszak/aspnetcore-angular2-universal :

    var nodeServices = Request.HttpContext.RequestServices.GetRequiredService<INodeServices>();
                    var hostEnv = Request.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
    
                    var applicationBasePath = hostEnv.ContentRootPath;
                    var requestFeature = Request.HttpContext.Features.Get<IHttpRequestFeature>();
                    var unencodedPathAndQuery = requestFeature.RawTarget;
                    var unencodedAbsoluteUrl = $"{Request.Scheme}://{Request.Host}{unencodedPathAndQuery}";
    
                    // ** TransferData concept **
                    // Here we can pass any Custom Data we want !
    
                    // By default we're passing down Cookies, Headers, Host from the Request object here
                    TransferData transferData = new TransferData();
                    transferData.request = AbstractHttpContextRequestInfo(Request);
                    transferData.thisCameFromDotNET = "Hi Angular it's asp.net :)";
                    // Add more customData here, add it to the TransferData class
    
                    //Prerender now needs CancellationToken
                    System.Threading.CancellationTokenSource cancelSource = new System.Threading.CancellationTokenSource();
                    System.Threading.CancellationToken cancelToken = cancelSource.Token;
    
                    // Prerender / Serialize application (with Universal)
                    var prerenderResult = await Prerenderer.RenderToString(
                              "/",
                              nodeServices,
                              cancelToken,
                              new JavaScriptModuleExport(applicationBasePath + "/ClientApp/dist/main-server"),
                              unencodedAbsoluteUrl,
                              unencodedPathAndQuery,
                              transferData, // Our simplified Request object & any other CustommData you want to send!
                              30000,
                              Request.PathBase.ToString()
                          );
    
  15. SteveSandersonMS commented on Sep 29, 2017

    @SteveSandersonMS
    Member

    Can you please also share if the same Node instance is used for all subsequent server side rendered requests?

    Yes, it is (at least, until you change any of your .js files on disk, at which point we recycle the Node process).

    As for slowdown elsewhere, I don't know why that would be happening and seems unrelated to this code. Sorry I can't help identify that!

  16. naveedahmed1 commented on Sep 29, 2017

    @naveedahmed1

    Thank you @SteveSandersonMS, but the bootstrap process for angular app on server occurs for each request correct? Is there any way to cache it?

  17. SteveSandersonMS commented on Sep 29, 2017

    @SteveSandersonMS
    Member

    Have a look at your boot.server.ts file for details on how this works. AFAIK Angular expects you to construct a new app platform instance to serve each request. But you might want to discuss this with the Angular community to find out if there are alternatives to that. You can edit your boot.server.ts file to put in whatever prerendering logic you want - this is independent of ASP.NET.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions