Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance issue in UseProxyToSpaDevelopmentServer #18062

Closed
sdcb opened this issue Dec 30, 2019 · 19 comments
Closed

Performance issue in UseProxyToSpaDevelopmentServer #18062

sdcb opened this issue Dec 30, 2019 · 19 comments
Assignees
Labels
affected-few This issue impacts only small number of customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-spa help wanted Up for grabs. We would accept a PR to help resolve this issue severity-minor This label is used by an internal tool
Milestone

Comments

@sdcb
Copy link

sdcb commented Dec 30, 2019

UseProxyToSpaDevelopmentServer causing a lot of time to forward the request.

The raw webpack/ng serve server is pretty fast, should be processed within 100ms, but UseProxyToSpaDevelopmentServer API have to wait for 4 seconds to handle this request.

To Reproduce

Create a angular SPA project (based on .NET Core 3.1), modify the Startup.cs, change UseAngularCliServer to UseProxyToSpaDevelopmentServer and hit Ctrl+F5 to run directly(and run ng serve in front-end folder at same time).

Checkout the browser F12, should see this:
image

When using raw webpack/ng serve command without proxy(http://localhost:4200), performance is much better:
image

Further technical details

  • .NET Core 3.1/3.1.100
  • Visual Studio 2019(16.4.2)
@sdcb
Copy link
Author

sdcb commented Dec 30, 2019

Looks like the issue is related to this one: #16797

@pranavkm
Copy link
Contributor

Do you know if the linked issue resolves your problem?

@pranavkm pranavkm added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Dec 30, 2019
@sdcb
Copy link
Author

sdcb commented Jan 2, 2020

@pranavkm I grab the latest code and does not seem help, it does not resolve my problem.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Jan 2, 2020
@pranavkm
Copy link
Contributor

pranavkm commented Jan 3, 2020

@javiercn this seems related to #18062.

@pranavkm pranavkm added investigate and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Jan 3, 2020
@pranavkm pranavkm added this to the 5.0.0-preview1 milestone Jan 3, 2020
@sdcb
Copy link
Author

sdcb commented Jan 15, 2020

This issue has two parts:

  • Proxy currently not using singleton HttpClient, so it not respect the ETag/If-None-Match header, and every request will need to wait webpack-dev-server for 4 seconds(that's why browser navigate is pretty fast)

  • So why webpack-dev-server need to wait for 4 seconds? I found that this simple code will need to wait 4 seconds:

const http = require('http');
const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('OK!');
    console.log('YEAH~');
})
server.listen(5000, 'localhost');

For reason unknown, just replace the localhost with 127.0.0.1, the 4 seconds waiting suddenly disappear, and I tried ASP.NET Core kestres server, using localhost is just fine/no waiting(I don't know why).

So, for reason unknown, I just need to replace the localhost with 127.0.0.1, I can gain a huge performance improvement, this is nothing related with .NET Core, seems a bug in node.js.

@javiercn
Copy link
Member

  • Proxy currently not using singleton HttpClient, so it not respect the ETag/If-None-Match header, and every request will need to wait webpack-dev-server for 4 seconds(that's why browser navigate is pretty fast)

Do you mean the HttpClient used by the spa extensions? There is no singleton HttpClient AFAIK on the SPA extensions, I'm not sure if it uses its own HttpClient and keeps it around or if it creates a new one every time.

With regards to the ETag / If-None-Match i don't think HttpClient has logic to handle those things or that we implement our own. Best case scenario, the OS handles it for you, but I don't think that's the case.

For reason unknown, just replace the localhost with 127.0.0.1, the 4 seconds waiting suddenly disappear, and I tried ASP.NET Core kestres server, using localhost is just fine/no waiting(I don't know why).

So, for reason unknown, I just need to replace the localhost with 127.0.0.1, I can gain a huge performance improvement, this is nothing related with .NET Core, seems a bug in node.js.

Is this code on the template? I'm not sure why localhost might be different than 127.0.0.1 but maybe the OS/network stack takes some kind of shortcut. @Tratcher is this something you know about?

@Tratcher
Copy link
Member

Localhost tries IPv6 first (::1) and takes seconds to time out before trying IPv4. I assume the server is only listening in IPv4?

@javiercn
Copy link
Member

@Tratcher Very likely. Do you see any downside to hardcoding 127.0.0.1 instead of localhost?

@Tratcher
Copy link
Member

shrug it's better to fix the server if possible.

@javiercn
Copy link
Member

@Tratcher I don't think we can fix the underlying webpack/node server. I'm not sure this is an issue in the general case either.

@sdcb
Copy link
Author

sdcb commented Jan 16, 2020

Well, I know the 4 seconds issue is not related to .NET, but if you guys were node.js experts, you may take a look on this:
image

Note that the elapsed time is intervaled every 4 seconds(4, 8, 12, 16, ...), but when I change the code from localhost to 127.0.0.1 or IPv6 version "::1", performance is much better(no 4 seconds delay).

@sdcb
Copy link
Author

sdcb commented Jan 16, 2020

Well, I find the reason, it is really the ipv6 bug in node.js, by default, node.js will only listen to ipv4 loopback:
image

In the mean time, ASP.NET Core will respect both ipv4 and ipv6:
image

when HttpClient sending a request to localhost, HttpClient will first try the ipv6 version (for 4 seconds), and the fallback to ipv4 version of loopback address, that's why the asp.net core UseProxyToSpaDevelopmentServer(localhost:4200) will have to wait 4 seconds in every front-end request, and modify it to 127.0.0.1:4200, performance is all good.

@Tratcher
Copy link
Member

But UseProxyToSpaDevelopmentServer([::1]:4200) works?

@sdcb
Copy link
Author

sdcb commented Jan 16, 2020

@Tratcher nop, as I said, node.js will treat localhost as ipv4 loopback address only, so by default ipv6 address is not working.

@sdcb
Copy link
Author

sdcb commented Jan 21, 2020

@Tratcher @javiercn
I believe Angular/React/Vue SPA extensions should using 127.0.0.1 instead of localhost here:

// Everything we proxy is hardcoded to target http://localhost because:
// - the requests are always from the local machine (we're not accepting remote
// requests that go directly to the Angular CLI middleware server)
// - given that, there's no reason to use https, and we couldn't even if we
// wanted to, because in general the Angular CLI server has no certificate
var targetUriTask = angularCliServerInfoTask.ContinueWith(
task => new UriBuilder("http", "localhost", task.Result.Port).Uri);

@javiercn
Copy link
Member

If @Tratcher is happy with the solution to change it to 127.0.0.1, I believe we would be happy to take a PR for this change.

@Tratcher
Copy link
Member

That's fine.

@mkArtakMSFT mkArtakMSFT added enhancement This issue represents an ask for new feature or an enhancement to an existing one help wanted Up for grabs. We would accept a PR to help resolve this issue labels Jun 9, 2020
@mkArtakMSFT
Copy link
Member

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@javiercn
Copy link
Member

This is a dupe of #22769

We recommend following the guidance offered there to avoid this issue.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 27, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-few This issue impacts only small number of customers area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-spa help wanted Up for grabs. We would accept a PR to help resolve this issue severity-minor This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests

5 participants