chrome-devtools-frontend
Version:
Chrome DevTools UI
62 lines (49 loc) • 2.45 kB
text/typescript
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import type * as Lantern from '../types/types.js';
// A DNS lookup will usually take ~1-2 roundtrips of connection latency plus the extra DNS routing time.
// Example: https://www.webpagetest.org/result/180703_3A_e33ec79747c002ed4d7bcbfc81462203/1/details/#waterfall_view_step1
// Example: https://www.webpagetest.org/result/180707_1M_89673eb633b5d98386de95dfcf9b33d5/1/details/#waterfall_view_step1
// DNS is highly variable though, many times it's a little more than 1, but can easily be 4-5x RTT.
// We'll use 2 since it seems to give the most accurate results on average, but this can be tweaked.
const DNS_RESOLUTION_RTT_MULTIPLIER = 2;
class DNSCache {
static rttMultiplier = DNS_RESOLUTION_RTT_MULTIPLIER;
rtt: number;
resolvedDomainNames: Map<string, {resolvedAt: number}>;
constructor({rtt}: {rtt: number}) {
this.rtt = rtt;
this.resolvedDomainNames = new Map();
}
getTimeUntilResolution(
request: Lantern.NetworkRequest, options?: {requestedAt?: number, shouldUpdateCache?: boolean}): number {
const {requestedAt = 0, shouldUpdateCache = false} = options || {};
const domain = request.parsedURL.host;
const cacheEntry = this.resolvedDomainNames.get(domain);
let timeUntilResolved = this.rtt * DNSCache.rttMultiplier;
if (cacheEntry) {
const timeUntilCachedIsResolved = Math.max(cacheEntry.resolvedAt - requestedAt, 0);
timeUntilResolved = Math.min(timeUntilCachedIsResolved, timeUntilResolved);
}
const resolvedAt = requestedAt + timeUntilResolved;
if (shouldUpdateCache) {
this.updateCacheResolvedAtIfNeeded(request, resolvedAt);
}
return timeUntilResolved;
}
updateCacheResolvedAtIfNeeded(request: Lantern.NetworkRequest, resolvedAt: number): void {
const domain = request.parsedURL.host;
const cacheEntry = this.resolvedDomainNames.get(domain) || {resolvedAt};
cacheEntry.resolvedAt = Math.min(cacheEntry.resolvedAt, resolvedAt);
this.resolvedDomainNames.set(domain, cacheEntry);
}
/**
* Forcefully sets the DNS resolution time for a request.
* Useful for testing and alternate execution simulations.
*/
setResolvedAt(domain: string, resolvedAt: number): void {
this.resolvedDomainNames.set(domain, {resolvedAt});
}
}
export {DNSCache};