How Would You Measure Early Hints with firstInterimResponseStart?
Question and context
Browsers are gaining PerformanceResourceTiming.firstInterimResponseStart, which records when the first byte of an interim 1xx response arrives. Implement an observer to evaluate whether 103 Early Hints reduce resource preparation time, including unsupported, cross-origin, and cached cases.
What the interviewer is testing
- Whether you understand
requestStart,firstInterimResponseStart, and final response-header timing. - Whether you know that zero can mean no 1xx, cross-origin masking, or a cache-related unavailable timestamp.
- Whether you can use
PerformanceObserverwith buffered entries and sampled reporting. - Whether you separate protocol benefit from browser support, Timing-Allow-Origin, and product metrics.
Clarifying questions to ask first
Measurement goal
Are we measuring time to the first 1xx, the number of Early Hints preloads, or user outcomes such as LCP and interaction readiness?
Resource scope
Should we observe only the same-origin navigation, or also CDN assets, fonts, and cross-origin scripts? Is Timing-Allow-Origin configured?
Compatibility policy
Will the data drive a live decision? Must older browsers provide an equivalent fallback metric when the property is unavailable?
A 30-second answer framework
I would use a PerformanceObserver and calculate firstInterimResponseStart - requestStart only when the property exists and is non-zero. Zero cannot prove that the server omitted 103 because cross-origin timing may be masked and cache paths can expose zero. The telemetry should record support, origin scope, and final response timing, then validate Early Hints against user metrics such as LCP.
Deep-dive answer steps
1. Explain the timestamps
requestStart is when the browser is about to request the resource; firstInterimResponseStart is when the first byte of a 1xx response arrives; finalResponseHeadersStart is when final response headers arrive. When an interim response exists, the first difference approximates network wait until that 1xx.
2. Write the observer
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
const interim = entry.firstInterimResponseStart;
if (typeof interim !== "number" || interim <= 0) continue;
reportTiming({
name: entry.name,
interimWait: interim - entry.requestStart,
finalHeaders: entry.finalResponseHeadersStart - interim,
initiator: entry.initiatorType,
});
}
});
observer.observe({ type: "resource", buffered: true });Production code should feature-detect the property and limit names, sampling, and fields so complete URLs or sensitive query parameters do not enter analytics.
3. Interpret zero correctly
Zero can mean no interim response, or that a cross-origin resource did not expose timing through Timing-Allow-Origin; cache hits and canceled requests can also produce zero for related timestamps. Dashboards should separate “not observed” from “confirmed no 1xx” and never turn zero into a negative duration or automatic failure.
4. Handle cross-origin resources
If a CDN or font is cross-origin, the server must return Timing-Allow-Origin for the permitted site before protected timing fields are exposed. Configure that header for actual deployment origins rather than every origin, and accept that some users remain unobservable because of policy.
5. Separate 103 from user benefit
The property reports the first 1xx timing; it does not identify 103 or prove that a preload was used. Confirm 103 with navigation data, server logs, or a controlled experiment, then compare finalResponseHeadersStart, resource responseEnd, and LCP. An early or incorrect preload can hurt performance even when the first 1xx arrives quickly.
6. Design compatibility fallback
Unsupported browsers can still report common requestStart, responseStart, and responseEnd metrics, but they cannot fabricate interim timing. Mark capability and aggregate old and new samples separately; a missing API must not block rendering.
7. Build verification and governance
Compare HTTP/2-or-later same-origin and cross-origin cases, cache hits and misses, and servers with and without 103. Assert interimWait >= 0 and that final headers do not precede the first interim response. Limit report frequency and interpret timing alongside LCP, preload hit rate, and error rate rather than treating a network timestamp as a product outcome.
A high-quality sample answer
I would use a buffered PerformanceObserver and report 1xx wait time only when firstInterimResponseStart exists and is non-zero. I would preserve zero as indeterminate, segment by origin, Timing-Allow-Origin, cache, and browser capability, and verify 103 with controlled experiments. Early Hints stays only if LCP, preload hit rate, and errors improve—not merely because an interim byte arrived sooner.
Common mistakes
- Treating a non-zero value as proof that the response was 103.
- Treating every zero as proof that the server sent no 1xx.
- Ignoring the data gap caused by missing cross-origin
Timing-Allow-Origin. - Using
responseStartas final-header time and mixing interim with final responses. - Calling
getEntriesByTypeonly after load and missing entries recorded earlier. - Watching network timing without checking LCP, preload hits, and errors.
Follow-up questions and answers
Can firstInterimResponseStart confirm 103?
No. It records the first byte of any 1xx response, including 100 Continue. Confirm 103 with server logs, controlled requests, and resource-loading behavior.
Why are cross-origin entries often zero?
Resource Timing masks cross-origin timestamps. Without a matching Timing-Allow-Origin, the protected fields return zero. Fix the response policy or classify the sample as unobservable; do not invent an estimate.
How do responseStart and finalResponseHeadersStart differ?
With an interim response, responseStart may reflect the first interim byte, while finalResponseHeadersStart represents final headers. Use the latter when measuring server preparation before the final response.
What is the fallback for older browsers?
Feature-detect the property, continue collecting common request and response times, and mark the missing interim field. Aggregate older-browser samples separately from new-API samples.
How do you prove Early Hints is worth keeping?
Run enabled and disabled cohorts with the same network, cache, and asset versions. Compare LCP, preload hit rate, final-header time, resource completion, and errors; an earlier 1xx is only intermediate evidence.