Switch to blob().text() for faster fetch parsing#76
Conversation
|
Please set a semver versioning label of either |
|
@tiagoad sorry for the direct ping. I wanted to follow up on this PR since it's been open for a while. Is there anything I should update or any requirements I might have missed to get it reviewed/merged? |
There was a problem hiding this comment.
@dmeremyanin Hey, thanks for this. Could you rebase onto current main?
There was a problem hiding this comment.
Hey, couple of things:
- The
blob.text().then(hook)isn't returned into the chain, so it's fire-and-forget. The next.then()(which firesonMeasurementResult) runs before the hook finishes.LoggingBandwidthEngineuses this hook to extract a token thatonMeasurementResultneeds — so there's a race condition. Need to return the promise so the chain waits for it.
something like this should work:
.then(r =>
r.blob().then(blob => {
if (this.#responseHook) {
return blob.text().then(body => {
this.#responseHook({ url, headers: r.headers, body });
return blob;
});
}
return blob;
})
)The key difference is return blob.text().then(...) — returning the promise so the chain waits for the hook to finish before continuing to the timing calculation.
-
That detached promise also has no
.catch()— errors get swallowed silently. -
Minor:
#responseHookdefaults tor => r, notnull, so theifguard is always true.blob.text()runs every time regardless.
I noticed that download speeds were significantly slower than expected (and much slower than upload speeds) when testing against a local Go-based backend.
It turns out
response.text()creates significant backpressure. Because JS handles the text chunks slower than the network can deliver them, it throttles the actual TCP connection. Usingresponse.blob().text()avoids JS backpressure and results in a more accurate network speed measurement.In local tests, the difference is substantial – around a 9-10x improvement. Below is a simple benchmark run in Chrome on a MacBook M4 Pro downloading a 100MB payload:
