1

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135
drdiogo
  • 21
  • 2

4 Answers4

0

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;
            }
        );
};
0

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.

Kevin Farrugia
  • 6,431
  • 4
  • 38
  • 61
0

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

cdaringe
  • 1,274
  • 2
  • 15
  • 33
0

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.

fetch event xhr event

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.

democrenes
  • 21
  • 4