Update:
I changed the API from fetch
to XMLHttpRequest
and I still see the problem.
According to the console logs the delay is between "readyState 1"(i.e. OPENED) and "readyState 2"(i.e HEADERS_RECEIVED).
Also, maybe it is worth mentioning, that in Firefox it works fine.
I would appreciate a couple of pointers on how to debug why the call to fetch()
takes 1 sec in chrome.
According to "network" tab the request took only 12ms. However in my logs and the "timeline" tab the fetch()
takes 1.06 sec. (Screenshots below).
Any tips on how to figure out what is stalling the fetch()
?
Network Tab screenshot:
Timeline Tab screenshot:
Update:
I changed the API from fetch
to XMLHttpRequest
and I still see the problem.
According to the console logs the delay is between "readyState 1"(i.e. OPENED) and "readyState 2"(i.e HEADERS_RECEIVED).
Also, maybe it is worth mentioning, that in Firefox it works fine.
I would appreciate a couple of pointers on how to debug why the call to fetch()
takes 1 sec in chrome.
According to "network" tab the request took only 12ms. However in my logs and the "timeline" tab the fetch()
takes 1.06 sec. (Screenshots below).
Any tips on how to figure out what is stalling the fetch()
?
Network Tab screenshot:
Timeline Tab screenshot:
Share Improve this question edited Sep 21, 2016 at 19:42 asked Sep 12, 2016 at 7:36 user6307701user6307701 18- Do you get any further information when you hover or click on the network panel entry? – Bergi Commented Sep 21, 2016 at 4:36
- In the "Network" Tab, where the entry is normal, I get extra information, but everything looks fine there. In the "Timeline" Tab, I don't get anything extra if I click on the long entry. – user6307701 Commented Sep 21, 2016 at 5:07
- second screenshot belongs to which tab? – Abhijeet Commented Sep 21, 2016 at 14:04
- @Abhijeet sorry if it was not clear. The second screenshot is for the "Timeline" Tab, for the exact same request. – user6307701 Commented Sep 21, 2016 at 19:41
- 1 I'd love to make an answer for you, but you need to write a working example for it to be based on - without the context, an example may be pointless. – TylerY86 Commented Sep 26, 2016 at 11:58
2 Answers
Reset to default 5 +200I'm wagering since the latency goes away when you have async: false
that it's due to something blocking the main thread.
Here, I get roughly 10 milliseconds for a simple request using Fetch inside of a WebWorker and posting the results back to the main thread.
var workerBlobs = Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return new Blob([oScript.textContent], {type: "text/javascript"}); });
var workers = workerBlobs.map(function(oBlob) { return new Worker(URL.createObjectURL(oBlob)); });
var log = document.getElementById('log');
function println(s) {
log.appendChild(document.createTextNode(s+'\n'));
}
workers[0].onmessage = function(oEvent) {
println("Done in " + ( performance.now() - start ).toFixed(4) + "ms" );
println(oEvent.data.message);
}
workers[0].onerror = function(oEvent) {
println("Error: "+JSON.stringify(oEvent.data));
}
var start = performance.now();
workers[0].postMessage('http://stacksnippets/');
#log {
white-space: pre-wrap;
}
<script type="text/js-worker">
onmessage = function (oEvent) {
fetch(oEvent.data).then(function(response) {
response.text().then(function(text){
console.log("response:",text);
postMessage({ type: 'response', message: text });
});
}).catch(function(err) {
console.error("error:",err);
postMessage({ type: 'error', message: err.toString(), stack: err.stack });
});
}
</script>
<pre id="log"></pre>
You'll have to excuse the error message when trying to execute; requests are somewhat cordoned inside that snippet sandbox. If I find a URL that works I'll throw it in. Use the jsfiddle example.
Edit: Updated jsfiddle example. There is some minor latency penalty incurred when using postMessage (in this example, approximately 5ms in chrome). Same 10ms average total. This might be worked around using transferrable array buffers and some other shenanigans.
To be more clear about this, you should be able to use this example to perform your fetch and timing on your worker thread, and then see how long it takes to get back to your main thread. If it takes far too much time to go from worker to main, something is blocking in the main JS thread. Then you have to hunt that down, and introduce some async flow to allow interspersion with your fetching and such.
Turns out it was a Chrome bug that has now been fixed in Chrome 54: https://bugs.chromium/p/chromium/issues/detail?id=649590#c1