Requests unexpectedly delayed due to an axios internal promise
See original GitHub issueDescription / Context
We are using axios in production and I’ve stumbled onto a peculiarity recently. Most of our XHR requests are made via axios but there was one that was made by leveraging XMLHttpRequest
directly. When looking at the request waterfall on webpagetest (a popular site for analyzing website performance), the request that is leveraging XMLHttpRequest
directly was being sent earlier than the requests leveraging axios. Here’s a snippet from webpagetest showing this:
Request #46
leverages XMLHttpRequest
directly and requests #49-54
leverage axios. The thing is: the requests are discovered in the code at around the same time. In fact, several of the axios requests are above request #46
in our code, (here is a simplified version):
So the requests are discovered around the same time but the axios calls are delayed by 200-300ms (up to 1000ms in certain cases) Why this is happening is a combination of two factors; axios creating a promise under the hood (before sending the request), and the main thread being busy with JavaScript execution (represented by the pink bar extending from request #30
). Here is a call stack of an axios XHR request (Note the Promise.then line):
To Reproduce
I’ve got a fork of axios with a reproducable comparison here: https://github.com/SashaKoro/axios
git clone https://github.com/SashaKoro/axios.git
yarn
yarn run examples
Open your browser’s devtools and navigate to http://localhost:3000/get
. The example sends three XHR requests; one via axios
, one via XMLHttpRequest
and one via fetch
. Afterwards, a long JavaScript while
loop ties up the main thread. Here is the code: https://github.com/SashaKoro/axios/blob/master/examples/get/index.html If you inspect the Dev Tools (Network tab), you will see something like this:
Three requests are sent, two at roughly the same time, but the third after a ~280ms delay (on my hardware) - the axios
request! Because axios
turned the request into a promise under the hood (before sending the request), the JavaScript event loop continues onward and runs the while
loop, which blocks the main thread and the axios
request is delayed from getting sent.
Expected behavior
The expected behavior is that an axios
request is sent when it is discovered in the consumers code. This is the behavior of vanilla XMLHttpRequest
and the Fetch
API. And this is usually the behavior in a lab like environment when axios
is being tested in isolation. However in a production environment where your website is doing all of the JavaScript this issue can creep up. Delayed XHR calls for critical content cause assets to be rendered later, affecting bounce rate / conversion rate and user experience.
Environment:
- Axios Version [0.19.0]
- Browser [Chrome]
- Browser Version [Latest]
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:10 (5 by maintainers)
Top GitHub Comments
In order to move fast on our end, we ended up forking axios with the changes I’ve made and deploying to production. The results have been incredible.
This is our homepage before:
And after:
Note the timing of the requests relative to the JS execution. Prior to the change, they were all bunched up at the end of the JS execution, now the requests are being made when they are discovered in the code.
Some of the requests are kicked off up to 500ms faster (this is on Chrome over broadband), on 3G connections we are seeing some requests kicked off up to a second faster.
#2702 has been merged, so this can be closed I assume?
Anyway, thanks for the improvement!