@@ -204,11 +204,15 @@ class NetworkAnalyzer {
204204 if ( ! Number . isFinite ( timing . sendStart ) || timing . sendStart < 0 ) return ;
205205
206206 // Assume everything before sendStart was just DNS + (SSL)? + TCP handshake
207- // 1 RT for DNS, 1 RT (maybe) for SSL, 1 RT for TCP
208- let roundTrips = 1 ;
207+ // 1 RT (maybe) for SSL, 1 RT for TCP
208+ // DNS is not included because
209+ // 1) it is very variable in terms of how many hops it could be (as little as 0, if cached locally)
210+ // 2) it doesn't even communicate with the server, so it is useless for RTT calculation.
211+ let roundTrips = 0 ;
209212 if ( ! record . protocol . startsWith ( 'h3' ) ) roundTrips += 1 ; // TCP
210213 if ( record . parsedURL . scheme === 'https' ) roundTrips += 1 ;
211- return timing . sendStart / roundTrips ;
214+ const dnsTime = timing . dnsStart >= 0 ? timing . dnsEnd - timing . dnsStart : 0 ;
215+ return ( timing . sendStart - dnsTime ) / roundTrips ;
212216 }
213217
214218 /**
@@ -237,13 +241,15 @@ class NetworkAnalyzer {
237241 // When connection was fresh...
238242 // TTFB = DNS + (SSL)? + TCP handshake + 1 RT for request + server response time
239243 if ( ! connectionReused ) {
240- roundTrips += 1 ; // DNS
244+ // We purposely exclude DNS from RTT estimate, as it is unrelated to RTT to the server.
241245 if ( ! record . protocol . startsWith ( 'h3' ) ) roundTrips += 1 ; // TCP
242246 if ( record . parsedURL . scheme === 'https' ) roundTrips += 1 ; // SSL
243247 }
244248
245- // subtract out our estimated server response time
246- return Math . max ( ( timing . receiveHeadersEnd - estimatedServerResponseTime ) / roundTrips , 3 ) ;
249+ // subtract out our estimated server response time and dns time
250+ const dnsTime = timing . dnsStart >= 0 ? timing . dnsEnd - timing . dnsStart : 0 ;
251+ const duration = timing . receiveHeadersEnd - estimatedServerResponseTime - dnsTime ;
252+ return Math . max ( duration / roundTrips , 3 ) ;
247253 }
248254
249255 /**
0 commit comments