Chrome stalls when making multiple requests to same resource?
Asked Answered
G

4

70

I'm trying to implement long polling for the first time, and I'm using XMLHttpRequest objects to do it. So far, I've been successful at getting events in Firefox and Internet Explorer 11, but Chrome strangely is the odd one out this time.

I can load one page and it runs just fine. It makes the request right away and starts processing and displaying events. If I open the page in a second tab, one of the pages starts seeing delays in receiving events. In the dev tools window, I see multiple requests with this kind of timing:

screenshot

"Stalled" will range up to 20 seconds. It won't happen on every request, but will usually happen on several requests in a row, and in one tab.

At first I thought this was an issue with my server, but then I opened two IE tabs and two Firefox tabs, and they all connect and receive the same events without stalling. Only Chrome is having this kind of trouble.

I figure this is likely an issue with the way in which I'm making or serving up the request. For reference, the request headers look like this:

Connection: keep-alive
Last-Event-Id: 530
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

The response looks like this:

HTTP/1.1 200 OK
Cache-Control: no-cache
Transfer-Encoding: chunked
Content-Type: text/event-stream
Expires: Tue, 16 Dec 2014 21:00:40 GMT
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 16 Dec 2014 21:00:40 GMT
Connection: close

In spite of the headers involved, I'm not using the browser's native EventSource, but rather a polyfill that lets me set additional headers. The polyfill is using XMLHttpRequest under the covers, but it seems to me that no matter how the request is being made, it shouldn't stall for 20 seconds.

What might be causing Chrome to stall like this?

Edit: Chrome's chrome://net-internals/#events page shows that there's a timeout error involved:

t=33627 [st=    5]      HTTP_CACHE_ADD_TO_ENTRY  [dt=20001]
                --> net_error = -409 (ERR_CACHE_LOCK_TIMEOUT)

The error message refers to a patch added to Chrome six months ago (https://codereview.chromium.org/345643003), which implements a 20-second timeout when the same resource is requested multiple times. In fact, one of the bugs the patch tries to fix (bug number 46104) refers to a similar situation, and the patch is meant to reduce the time spent waiting.

It's possible the answer (or workaround) here is just to make the requests look different, although perhaps Chrome could respect the "no-cache" header I'm setting.

Graffito answered 16/12, 2014 at 21:11 Comment(6)
It says there's no issue with number 46104Beekeeper
Follow the BUG link with that number at the bottom of the issue I linked above.Graffito
Or let me see if I can link it directly now: code.google.com/p/chromium/issues/detail?id=46104Graffito
Is this the same as I experience here? Using Chrome 42 youtube.com/watch?v=PYorlA63ZzI&feature=youtu.be&hd=1Verne
In chrome 75.0.3770.100 non of the mentioned approaches worked - any ideas how to solve this issue?Vinegarish
Looks like this is still the same, nearly 10 years later: #78386328Shira
G
60

Yes, this behavior is due to Chrome locking the cache and waiting to see the result of one request before requesting the same resource again. The answer is to find a way to make the requests unique. I added a random number to the query string, and everything is working now.

For future reference, this was Chrome 39.0.2171.95.

Edit: Since this answer, I've come to understand that "Cache-Control: no-cache" doesn't do what I thought it does. Despite its name, responses with this header can be cached. I haven't tried, but I wonder if using "Cache-Control: no-store", which does prevent caching, would fix the issue.

Graffito answered 16/12, 2014 at 21:52 Comment(20)
Does that mean that if you repeatedly request your site by spamming [F5] on your keyboard Chrome will visually "hang" on loading?Dumbhead
I don't think so. More like if you loaded the same page in multiple tabs at the same time. The cache hang happens when making multiple requests to the same URL at the same time. In my case, these were long-poll responses, so on the second request, Chrome would wait for the first request to complete to see if it could reuse the response. The first request would take longer than 20 seconds to finish, and Chrome would wait that long before giving up.Graffito
Could you please check website hash.fm and test it a little bit? I'm currently handling such bug report and what's interesting latest Firefox has no problem with that, but Chrome (41.0.2272.101) stalls requests after several (different every time) refreshes. When I repeatedly hit [F5] website of course loads a little bit slower but with Firefox I see everything in Apache access logs, Chrome does not even send a request. Thanks in advance.Dumbhead
When looking at your site, I don't see much time spent in "stalled." It doesn't appear to be the same phenomenon. I do see one major thing making your site slow; a lot of responses are coming back with the "Connection: close" header, which kills streamlining and makes the site very dependent on the number of connections the browser can make to the site. This may cause what you're seeing. Also, at this moment, the server has stopped serving a lot of the resources to me; I'm seeing connections just timeout. Get streamlining working and then try again.Graffito
Strike the comment about the server not sending me resources; my Chrome tab apparently got stuck after so many reloads. I've also disabled an extension that was making the connections appear worse than they were. I'm definitely not seeing any cache issues, because your site hardly uses the cache. Biggest issue is still Connection: close. I'm seeing a stall time of 18ms for the very first resources because they can't reuse the initial page connection. They have to wait for a new one because the initial page closes its connection.Graffito
I do see one other interesting thing: on refresh, Chrome says that it's sending the headers and not getting a response for awhile. See my capture at pastebin.com/K46kH7pi. In that capture there's a two second delay between sending the request and receiving the reply headers. That would be the TTFB stat in Chrome's network timing screen. Perhaps your server is getting overwhelmed servicing all those connections?Graffito
Adding a random query string unfortunately didn't work for me; any other suggestions on how to make the request appear unique?Eureka
If you have two requests with different URLs, they should not be blocking each other in the cache. Are you seeing 20 seconds of stalling?Graffito
Hey guys, did you ever solve this? I'm experiencing a similar thing. I have a plugin that makes API on every page load via ajax, but chrome hangs for a bit then it loads it fine for like 30 requests, then it will hang again. While it is hanging. I can open up safari, make the same request and it loads just fine. I paste the same url in chrome, it hangs.Concertgoer
Here is what i'm seeing pastebin.com/C2KWqgis Notice the delays around: t=64063 [st=66671] HTTP_STREAM_PARSER_READ_HEADERS [dt=72] t=64135 [st=66743] HTTP_TRANSACTION_READ_RESPONSE_HEADERSConcertgoer
I'm on Chrome for Mac 44.0.2403.130Concertgoer
You're likely also seeing something else. If you were hitting the cache lock, it would have timed out after 20 seconds. You're seeing delays of 60 seconds. The pastebin you sent doesn't show where the time is being spent (look for the line where dt is large), only that it happened before the HTTP_TRANSACTION_SEND_REQUEST completed.Graffito
Cache-Control: no-store worked for me! Very helpful nice answer, thank you :DSitar
Cache-Control: no-store didn't work well for me somehow while adding a random number worked like a charmOrnithopter
I was having this issue and Cache-Control: no-cache, no-store worked for me. Big thanks!Magistracy
I deliberately put in a 10 second "sleep" in the server and found that if I refresh 2 chrome windows with the same url at the same time, the first one takes 10 seconds and the second takes 20. I can see from the server logs that chrome doesn't send the second request until the first has completed, though it shows the status as "pending" in the second window for the whole 20 seconds. This is regardless of HTTP headers. This doesn't happen if the URLs are different or with firefox.Heulandite
Unluckily Cache-Control: no-store || Cache-Control: no-cache, no-store won't launch multiple requests. With FF it's ok!, Chrome ver.: 89.0.4389.90Neumeyer
In case it wasn't obvious, doing Cache-Control: no-cache, no-store will prevent chrome from caching the response, which seems fine for the OP, but might degrade other use cases. Also note that each new URL could trigger an additional OPTIONS request for CORS roundtrip if you're setting non-simple headers (e.g. Range). bugs.chromium.org/p/chromium/issues/detail?id=969828 seems to be about making this fasterBoon
accepted answer is not actually working anymore. adding cache-control does not allow parallel requests in newer chrome version (I checked at version 100)Orgiastic
After trying all those above solutions i didnt find the solution. So i opened two tabs with both another PHP page on the same domain. The first one had a sleep(10), the other direct PHP processing. The apache log told me both were sent directly, but the writing order of the log was mixed. So Chrome didnt cause the delay. It turned out PHP was creating the delay. serverfault.com/a/194449/454355 helped me: session_start() creates a session file LOCK, which blocks all other requests until the current page load completes. By calling session_write_close() the lock is removed. Then it works!Preceding
M
2

adding Cache-Control: no-cache, no-transform worked for me

Musician answered 29/11, 2017 at 23:19 Comment(0)
C
2

I have decided to keep it simple and checked the response headers of a website that did not have this issue and I changed my response headers to match theirs:

Cache-Control: max-age=3, must-revalidate
Cacodyl answered 5/10, 2018 at 14:9 Comment(0)
A
0

I ran into the same issue. Cache-Control header didn't help. But I just added extra query parameter with random value and made all requests unique. And it worked.

GET /long-polling?rand=123

GET /long-polling?rand=456

Chrome considered them as different requests.

Ambagious answered 2/7, 2023 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.