I was wondering if there's anyway of computing the TTFB (Time to First Byte) or Wait time using fetch API, or simply time of the arrival of the first chunk on the client side.
4 Answers
I've managed to find a way to find the ttfb and how long the request took.
const realFetch = window.fetch;
window.fetch = function () {
const prom = realFetch.apply(this, arguments);
const start = Date.now();
return prom.then((response) => {
const reader = response.body.getReader();
return new ReadableStream({
start(controller) {
let begin = false;
return pump();
function pump() {
return reader.read().then(({done, value}) => {
if (!begin) {
console.log("ttfb: " + (Date.now() - start));
begin = true;
}
if (done) {
console.log("end: " + (Date.now() - start));
controller.close();
return;
}
controller.enqueue(value);
return pump();
});
}
}
})
})
.then(stream => new Response(stream))
.catch((err) => {
throw err;
}
);
};

- 9
- 2
-
2This is not TTFB. This is TT-first-chunk-of-body – cdaringe Jul 19 '21 at 23:53
You are easily able to measure it with Chrome Dev Tools. Assuming you do not have access to DevTools, you could use the Resource Timing API.
For example:
const fetchTiming = performance.getEntriesByType("resource")
.find(n => n.initiatorType === "fetch");
const TTFB = fetchTiming.responseStart - fetchTiming.requestStart
Note: You need to filter the performance.getEntriesByType("resource")
to retrieve the fetch
you need as there may be multiple entries and the above example assumes the first entry.

- 6,431
- 4
- 38
- 61
-
1
-
@cdaringe you are correct and I have updated my answer accordingly. – Kevin Farrugia Jul 20 '21 at 08:43
PerformanceResourceTiming API is what is desired.
https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming
This poster shows code that demonstrates usage: PerformanceResourceTiming.responseStart and PerformanceResourceTiming.requestStart both are 0 for a status ok http request

- 1,274
- 2
- 15
- 33
It's not as simple as the other answers suggest. You must have explicit permission from the server to calculate TTFB with the PerformanceResourceTiming
(PRT) API. Your request URL must be allow listed for cross origin timing in the response header's Timing-Allow-Origin
.
All requests initiated by Fetch / Xhr are captured by PRT. We can listen for this by inserting this snippet at the top of your web application.
// Log all resource entries at this point
const resources = performance.getEntriesByType("resource");
resources.forEach((entry) => {
console.log(`${entry.name}'s duration: ${entry.duration}`);
});
// PerformanceObserver version
// Log all resource entries when they are available
function perfObserver(list: any, observer: any) {
list.getEntriesByType("resource").forEach((entry: PerformanceResourceTiming) => {
console.log(entry.name, entry);
});
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ entryTypes: ["resource", "navigation"] });
Here, PerformanceObserver
captures two calls to the Reddit API initiated by Fetch and XHR. However, responseStart
and requestStart
are zeroed out because Reddit does not allow list my URL (localhost). In consequence, I can't calculate TTFB
= responseStart
- requestStart
.
You can get the overall duration though, which is the round trip latency of your request.
Tl; DR: you can use PRT to calculate TFB of Fetch/Xhr; however, you must have explicit permission from the server to do so. Otherwise, you are stuck with overall duration only.

- 21
- 4