We have an API which randomly takes high content download
time in chrome, It works fine always in firefox and takes an only few ms
. The response size is 20kb uncompressed and 4kb compressed. The same request also works fine using curl.
Things that we have tried:
- Disabling
If-None-Match
header to disable cache response from the browser. - Trying various compressions (gzip, deflate, br).
- Disabling compression.
- Disabling all chrome extensions.
The same request works fine sometimes on chrome but randomly returns very high content download time.
We are unable to understand the root cause of this issue. What are the other things we can try to minimize this time?
I made three requests here and the 3rd one took the most time (before the last spike). CPU does not seem to be maxing out for a longer period of time. Most of the time is idle time.
Also, When replaying the call using Replay XHR
menu, the Content download period drops from 2s to 200 ms.
Are you by chance trying to implement infinite scrolling? If you are, try dragging the scroll bar instead of using the mouse wheel. For some reason, Chrome seems to struggle with mouse scroll events. If the scroll bar worked just fine, keep reading.
This post provides a detailed walkthrough of someone experiencing something similar - https://github.com/TryGhost/Ghost/issues/7934
I had attached a watcher on the
scroll
event which would trigger an AJAX request. I had throttled the request and could see that only 1 was being sent. I watched my dev server return the response within a few ms but there would be a 2 second delay in chrome. No render, no api calls, no and scripts executing. But the "Content Download" would take 3 seconds for 14kb. No other browser had this issue.I stumbled upon suggestions that using
requestAnimationFrame
instead ofsetTimeout
would solve the problem. That approach seems that approach works when the "Waiting" or green is significant, not so much for the "Content Download" or blue.After hours of digging, I tried conditionally calling
e.preventDefault()
on themousewheel
event and to my amazement, it worked.A few things to note:
1) I did not use the
mousewheel
event to make the api call. I used thescroll
event along with throttling.2) The
mousewheel
event is non-standard and should not be used. See https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel3) BUT in this case, you have to watch and handle the
mousewheel
event because of chrome. Other browsers ignore the event if they don't support it and I have yet to see it cause an issue in another browser.4) You don't want to call
preventDefault()
every time because that disables scrolling with a mouse :) You only want to call it whendeltaY
is 1 if you are using vertical scroll. You can see from the attached image thatdeltaY
is 1 when you basically can't scroll anymore. themousewheel
event is fired even though the page cannot scroll. As a side note,deltaX
is -0 when you are scrolling vertically anddeltaY
is -0 when scrolling horizontally.My solution:
That has been the only solution that I've seen work and I haven't seen it mentioned or discussed elsewhere. I hope that helps.
console log of mousewheel event
I think you may be doing it wrong.™
Fundamentally, if this really only happens with Chrome, then perhaps the client-side code is to blame, of which you don't reveal any details.
Otherwise, you are trying to debug what you present as a backend condition (based on the choice on the nginx tag) with front-end tools:
Have you tried using
tcpdump(8)
to troubleshoot the issue? What packets gets exchanged and at what times?Have you tried logging the times of the request being received and processed by nginx? E.g.,
$request_time
?Where is the server located? Perhaps you're experiencing packet loss, which may require timeouts and retransmission of some TCP packets, which invariably will introduce a random delay?
Finally, the last possibility is that the field doesn't mean what you think it does -- it sounds like it may take a hit from CPU load, as this is the result of the
XMLHTTPRequest
(XHR
) processing -- perhaps you run some advertising with user tracking that randomly consumes a significant amount of CPU, slowing down your metrics?