diff --git a/core/lib/dependency-graph/simulator/network-analyzer.js b/core/lib/dependency-graph/simulator/network-analyzer.js index 9962dab6070c..d2774dbb5c00 100644 --- a/core/lib/dependency-graph/simulator/network-analyzer.js +++ b/core/lib/dependency-graph/simulator/network-analyzer.js @@ -204,11 +204,15 @@ class NetworkAnalyzer { if (!Number.isFinite(timing.sendStart) || timing.sendStart < 0) return; // Assume everything before sendStart was just DNS + (SSL)? + TCP handshake - // 1 RT for DNS, 1 RT (maybe) for SSL, 1 RT for TCP - let roundTrips = 1; + // 1 RT (maybe) for SSL, 1 RT for TCP + // DNS is not included because + // 1) it is very variable in terms of how many hops it could be (as little as 0, if cached locally) + // 2) it doesn't even communicate with the server, so it is useless for RTT calculation. + let roundTrips = 0; if (!record.protocol.startsWith('h3')) roundTrips += 1; // TCP if (record.parsedURL.scheme === 'https') roundTrips += 1; - return timing.sendStart / roundTrips; + const dnsTime = timing.dnsStart >= 0 ? timing.dnsEnd - timing.dnsStart : 0; + return (timing.sendStart - dnsTime) / roundTrips; } /** @@ -237,13 +241,15 @@ class NetworkAnalyzer { // When connection was fresh... // TTFB = DNS + (SSL)? + TCP handshake + 1 RT for request + server response time if (!connectionReused) { - roundTrips += 1; // DNS + // We purposely exclude DNS from RTT estimate, as it is unrelated to RTT to the server. if (!record.protocol.startsWith('h3')) roundTrips += 1; // TCP if (record.parsedURL.scheme === 'https') roundTrips += 1; // SSL } - // subtract out our estimated server response time - return Math.max((timing.receiveHeadersEnd - estimatedServerResponseTime) / roundTrips, 3); + // subtract out our estimated server response time and dns time + const dnsTime = timing.dnsStart >= 0 ? timing.dnsEnd - timing.dnsStart : 0; + const duration = timing.receiveHeadersEnd - estimatedServerResponseTime - dnsTime; + return Math.max(duration / roundTrips, 3); } /** diff --git a/core/test/audits/largest-contentful-paint-element-test.js b/core/test/audits/largest-contentful-paint-element-test.js index 5ecdcb3f0734..0279e5c7144b 100644 --- a/core/test/audits/largest-contentful-paint-element-test.js +++ b/core/test/audits/largest-contentful-paint-element-test.js @@ -114,11 +114,11 @@ describe('Performance: largest-contentful-paint-element audit', () => { expect(auditResult.details.items[1].items[0].phase).toBeDisplayString('TTFB'); expect(auditResult.details.items[1].items[0].timing).toBeCloseTo(800, 0.1); expect(auditResult.details.items[1].items[1].phase).toBeDisplayString('Load Delay'); - expect(auditResult.details.items[1].items[1].timing).toBeCloseTo(651, 0.1); + expect(auditResult.details.items[1].items[1].timing).toBeCloseTo(650.25, 0.1); expect(auditResult.details.items[1].items[2].phase).toBeDisplayString('Load Time'); - expect(auditResult.details.items[1].items[2].timing).toBeCloseTo(1813.7, 0.1); + expect(auditResult.details.items[1].items[2].timing).toBeCloseTo(1812.8, 0.1); expect(auditResult.details.items[1].items[3].phase).toBeDisplayString('Render Delay'); - expect(auditResult.details.items[1].items[3].timing).toBeCloseTo(2539.2, 0.1); + expect(auditResult.details.items[1].items[3].timing).toBeCloseTo(2537.9, 0.1); }); it('doesn\'t throw an error when there is nothing to show', async () => { diff --git a/core/test/computed/metrics/lantern-largest-contentful-paint-test.js b/core/test/computed/metrics/lantern-largest-contentful-paint-test.js index 589f0f797273..77fcf6298e36 100644 --- a/core/test/computed/metrics/lantern-largest-contentful-paint-test.js +++ b/core/test/computed/metrics/lantern-largest-contentful-paint-test.js @@ -24,14 +24,14 @@ describe('Metrics: Lantern LCP', () => { ); expect({ - timing: Math.round(result.timing), - optimistic: Math.round(result.optimisticEstimate.timeInMs), - pessimistic: Math.round(result.pessimisticEstimate.timeInMs)}). + timing: Math.round(result.timing), + optimistic: Math.round(result.optimisticEstimate.timeInMs), + pessimistic: Math.round(result.pessimisticEstimate.timeInMs) }). toMatchInlineSnapshot(` Object { - "optimistic": 2294, - "pessimistic": 3233, - "timing": 2764, + "optimistic": 2293, + "pessimistic": 3232, + "timing": 2763, } `); assert.equal(result.optimisticEstimate.nodeTimings.size, 12); diff --git a/core/test/computed/metrics/largest-contentful-paint-test.js b/core/test/computed/metrics/largest-contentful-paint-test.js index f9d61a6b13fb..4c2db92cf520 100644 --- a/core/test/computed/metrics/largest-contentful-paint-test.js +++ b/core/test/computed/metrics/largest-contentful-paint-test.js @@ -25,14 +25,14 @@ describe('Metrics: LCP', () => { settings, URL}, context); expect({ - timing: Math.round(result.timing), - optimistic: Math.round(result.optimisticEstimate.timeInMs), - pessimistic: Math.round(result.pessimisticEstimate.timeInMs)}). + timing: Math.round(result.timing), + optimistic: Math.round(result.optimisticEstimate.timeInMs), + pessimistic: Math.round(result.pessimisticEstimate.timeInMs) }). toMatchInlineSnapshot(` Object { - "optimistic": 2294, - "pessimistic": 3233, - "timing": 2764, + "optimistic": 2293, + "pessimistic": 3232, + "timing": 2763, } `); }); diff --git a/core/test/computed/metrics/lcp-breakdown-test.js b/core/test/computed/metrics/lcp-breakdown-test.js index 2e380e2ae8d2..1a86031df337 100644 --- a/core/test/computed/metrics/lcp-breakdown-test.js +++ b/core/test/computed/metrics/lcp-breakdown-test.js @@ -129,8 +129,8 @@ describe('LCPBreakdown', () => { const result = await LCPBreakdown.request(data, {computedCache: new Map()}); expect(result.ttfb).toBeCloseTo(800, 0.1); - expect(result.loadStart).toBeCloseTo(2579.5, 0.1); - expect(result.loadEnd).toBeCloseTo(5804, 0.1); + expect(result.loadStart).toBeCloseTo(2578.2, 0.1); + expect(result.loadEnd).toBeCloseTo(5801, 0.1); }); it('returns observed for image LCP', async () => { diff --git a/core/test/computed/metrics/time-to-first-byte-test.js b/core/test/computed/metrics/time-to-first-byte-test.js index e2f111200910..eb1250485add 100644 --- a/core/test/computed/metrics/time-to-first-byte-test.js +++ b/core/test/computed/metrics/time-to-first-byte-test.js @@ -91,7 +91,7 @@ describe('Metrics: TTFB', () => { // 3 * 150 RTT + 99 server response time // 99 Comes from (100ms observed TTFB - 1ms observed RTT) - expect(result.timing).toEqual(549); + expect(result.timing).toEqual(548.5); expect(result.timestamp).toBeUndefined(); }); @@ -105,7 +105,7 @@ describe('Metrics: TTFB', () => { // 4 * 150 RTT + 99.1 server response time // 99.1 Comes from (100ms observed TTFB - 0.9ms observed RTT) - expect(result.timing).toEqual(699.1); + expect(result.timing).toEqual(699); expect(result.timestamp).toBeUndefined(); }); diff --git a/core/test/computed/network-analysis-test.js b/core/test/computed/network-analysis-test.js index d0a3f8ce00c8..5eb7909a9663 100644 --- a/core/test/computed/network-analysis-test.js +++ b/core/test/computed/network-analysis-test.js @@ -46,9 +46,24 @@ Map { }); const result = await NetworkAnalysis.request(mutatedLog, {computedCache: new Map()}); - // If the connection timings were not removed, this would be the 1.045 estimate as seen in + // If the connection timings were not removed, these estimates would be the same as in // the test above. However, without connection timings we fall back to a coarse estimate and - // get this instead. - expect(result.additionalRttByOrigin.get('https://www.google-analytics.com')).toBeCloseTo(2.86); + // get slightly different results. + expect(result.additionalRttByOrigin).toMatchInlineSnapshot(` +Map { + "https://pwa.rocks" => 0.8417000135522703, + "https://www.googletagmanager.com" => 0.4456999959075678, + "https://www.google-analytics.com" => 0, + "__SUMMARY__" => 0, +} +`); + expect(result.serverResponseTimeByOrigin).toMatchInlineSnapshot(` +Map { + "https://pwa.rocks" => 159.70249997917608, + "https://www.googletagmanager.com" => 153.03200000198592, + "https://www.google-analytics.com" => 161.04569999879467, + "__SUMMARY__" => 159.70249997917608, +} +`); }); }); diff --git a/core/test/fixtures/fraggle-rock/reports/sample-flow-result.json b/core/test/fixtures/fraggle-rock/reports/sample-flow-result.json index fe74b9276166..a78c2538ad90 100644 --- a/core/test/fixtures/fraggle-rock/reports/sample-flow-result.json +++ b/core/test/fixtures/fraggle-rock/reports/sample-flow-result.json @@ -46,7 +46,7 @@ "description": "First Contentful Paint marks the time at which the first text or image is painted. [Learn more about the First Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/).", "score": 0.97, "scoreDisplayMode": "numeric", - "numericValue": 1372.2951999999998, + "numericValue": 1372.1713000000002, "numericUnit": "millisecond", "displayValue": "1.4 s" }, @@ -56,7 +56,7 @@ "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 1372.2951999999998, + "numericValue": 1372.1713000000002, "numericUnit": "millisecond", "displayValue": "1.4 s" }, @@ -66,7 +66,7 @@ "description": "First Meaningful Paint measures when the primary content of a page is visible. [Learn more about the First Meaningful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/first-meaningful-paint/).", "score": 0.99, "scoreDisplayMode": "numeric", - "numericValue": 1372.2951999999998, + "numericValue": 1372.1713000000002, "numericUnit": "millisecond", "displayValue": "1.4 s" }, @@ -76,7 +76,7 @@ "description": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more about the Speed Index metric](https://developer.chrome.com/docs/lighthouse/performance/speed-index/).", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 1372.2951999999998, + "numericValue": 1372.1713000000002, "numericUnit": "millisecond", "displayValue": "1.4 s" }, @@ -234,7 +234,7 @@ "description": "Time to Interactive is the amount of time it takes for the page to become fully interactive. [Learn more about the Time to Interactive metric](https://developer.chrome.com/docs/lighthouse/performance/interactive/).", "score": 0.99, "scoreDisplayMode": "numeric", - "numericValue": 2369.0733999999998, + "numericValue": 2368.8256, "numericUnit": "millisecond", "displayValue": "2.4 s" }, @@ -661,7 +661,7 @@ "numTasksOver50ms": 0, "numTasksOver100ms": 0, "numTasksOver500ms": 0, - "rtt": 0.041299999999999996, + "rtt": 0.06194999999999999, "throughput": 28471144.280089427, "maxRtt": 162.331, "maxServerLatency": 22.397999999999982, @@ -1180,7 +1180,7 @@ }, { "origin": "https://fonts.gstatic.com", - "rtt": 0.041299999999999996 + "rtt": 0.06194999999999999 } ], "sortedBy": [ @@ -1219,7 +1219,7 @@ }, { "origin": "https://fonts.gstatic.com", - "serverResponseTime": 20.6937 + "serverResponseTime": 20.67305 }, { "origin": "https://www.mikescerealshack.co", @@ -1592,17 +1592,17 @@ }, { "phase": "Load Delay", - "timing": 385.68235231964275, + "timing": 385.5920476244488, "percent": "28%" }, { "phase": "Load Time", - "timing": 78.082398686087, + "timing": 78.07534888426801, "percent": "6%" }, { "phase": "Render Delay", - "timing": 294.01344899427, + "timing": 293.98690349128333, "percent": "21%" } ] @@ -1800,17 +1800,17 @@ { "url": "https://www.mikescerealshack.co/_next/static/chunks/framework.9d524150d48315f49e80.js", "duration": 193, - "startTime": 2176.0733999999998 + "startTime": 2175.8256 }, { "url": "https://www.mikescerealshack.co/", "duration": 127, - "startTime": 779.9060999999999 + "startTime": 779.8441500000001 }, { "url": "https://www.mikescerealshack.co/", "duration": 96, - "startTime": 975.9060999999999 + "startTime": 975.8441500000001 } ], "sortedBy": [ @@ -1828,21 +1828,21 @@ "tasks": [ { "urlIndex": 0, - "startTime": 2176.1, + "startTime": 2175.8, "duration": 193, "other": 193, "scriptEvaluation": 0 }, { "urlIndex": 1, - "startTime": 779.9, + "startTime": 779.8, "duration": 127, "other": 127, "scriptEvaluation": 0 }, { "urlIndex": 1, - "startTime": 975.9, + "startTime": 975.8, "duration": 96, "other": 96, "paintCompositeRender": 0, @@ -6863,31 +6863,31 @@ "core/lib/i18n/i18n.js | seconds": [ { "values": { - "timeInMs": 1372.2951999999998 + "timeInMs": 1372.1713000000002 }, "path": "audits[first-contentful-paint].displayValue" }, { "values": { - "timeInMs": 1372.2951999999998 + "timeInMs": 1372.1713000000002 }, "path": "audits[largest-contentful-paint].displayValue" }, { "values": { - "timeInMs": 1372.2951999999998 + "timeInMs": 1372.1713000000002 }, "path": "audits[first-meaningful-paint].displayValue" }, { "values": { - "timeInMs": 1372.2951999999998 + "timeInMs": 1372.1713000000002 }, "path": "audits[speed-index].displayValue" }, { "values": { - "timeInMs": 2369.0733999999998 + "timeInMs": 2368.8256 }, "path": "audits.interactive.displayValue" }, @@ -6955,7 +6955,7 @@ }, { "values": { - "timeInMs": 1372.2951999999998 + "timeInMs": 1372.1713000000002 }, "path": "audits[largest-contentful-paint-element].displayValue" } @@ -9150,7 +9150,7 @@ }, { "origin": "https://www.mikescerealshack.co", - "rtt": 0.0901 + "rtt": 0.13515 } ], "sortedBy": [ @@ -9189,7 +9189,7 @@ }, { "origin": "https://www.mikescerealshack.co", - "serverResponseTime": 574.9549 + "serverResponseTime": 574.90985 }, { "origin": "https://mnl4bjjsnz-dsn.algolia.net", @@ -17376,7 +17376,7 @@ "description": "First Contentful Paint marks the time at which the first text or image is painted. [Learn more about the First Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/first-contentful-paint/).", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 866.7026, + "numericValue": 866.7448999999999, "numericUnit": "millisecond", "displayValue": "0.9 s" }, @@ -17386,7 +17386,7 @@ "description": "Largest Contentful Paint marks the time at which the largest text or image is painted. [Learn more about the Largest Contentful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint/)", "score": 0.98, "scoreDisplayMode": "numeric", - "numericValue": 1803.0092, + "numericValue": 1803.2048, "numericUnit": "millisecond", "displayValue": "1.8 s" }, @@ -17396,7 +17396,7 @@ "description": "First Meaningful Paint measures when the primary content of a page is visible. [Learn more about the First Meaningful Paint metric](https://developer.chrome.com/docs/lighthouse/performance/first-meaningful-paint/).", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 866.7026, + "numericValue": 866.7448999999999, "numericUnit": "millisecond", "displayValue": "0.9 s" }, @@ -17406,7 +17406,7 @@ "description": "Speed Index shows how quickly the contents of a page are visibly populated. [Learn more about the Speed Index metric](https://developer.chrome.com/docs/lighthouse/performance/speed-index/).", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 866.7026, + "numericValue": 866.7448999999999, "numericUnit": "millisecond", "displayValue": "0.9 s" }, @@ -17564,7 +17564,7 @@ "description": "Time to Interactive is the amount of time it takes for the page to become fully interactive. [Learn more about the Time to Interactive metric](https://developer.chrome.com/docs/lighthouse/performance/interactive/).", "score": 1, "scoreDisplayMode": "numeric", - "numericValue": 925.2026, + "numericValue": 925.2448999999999, "numericUnit": "millisecond", "displayValue": "0.9 s" }, @@ -17997,10 +17997,10 @@ "numTasksOver50ms": 0, "numTasksOver100ms": 0, "numTasksOver500ms": 0, - "rtt": 0.003, + "rtt": 0.0045, "throughput": 48594453.24888648, - "maxRtt": 0.0468, - "maxServerLatency": 3.5377, + "maxRtt": 0.0702, + "maxServerLatency": 3.53605, "totalByteWeight": 127688, "totalTaskTime": 113.59800000000007, "mainDocumentTransferSize": 3596 @@ -18449,7 +18449,7 @@ "description": "Network round trip times (RTT) have a large impact on performance. If the RTT to an origin is high, it's an indication that servers closer to the user could improve performance. [Learn more about the Round Trip Time](https://hpbn.co/primer-on-latency-and-bandwidth/).", "score": null, "scoreDisplayMode": "informative", - "numericValue": 0.0468, + "numericValue": 0.0702, "numericUnit": "millisecond", "displayValue": "0 ms", "details": { @@ -18470,19 +18470,19 @@ "items": [ { "origin": "https://www.mikescerealshack.co", - "rtt": 0.0468 + "rtt": 0.0702 }, { "origin": "https://events.mikescerealshack.co", - "rtt": 0.0039 + "rtt": 0.00585 }, { "origin": "https://fonts.googleapis.com", - "rtt": 0.0033000000000000004 + "rtt": 0.00495 }, { "origin": "https://fonts.gstatic.com", - "rtt": 0.003 + "rtt": 0.0045 } ], "sortedBy": [ @@ -18496,7 +18496,7 @@ "description": "Server latencies can impact web performance. If the server latency of an origin is high, it's an indication the server is overloaded or has poor backend performance. [Learn more about server response time](https://hpbn.co/primer-on-web-performance/#analyzing-the-resource-waterfall).", "score": null, "scoreDisplayMode": "informative", - "numericValue": 3.5377, + "numericValue": 3.53605, "numericUnit": "millisecond", "displayValue": "0 ms", "details": { @@ -18517,19 +18517,19 @@ "items": [ { "origin": "https://fonts.googleapis.com", - "serverResponseTime": 3.5377 + "serverResponseTime": 3.53605 }, { "origin": "https://www.mikescerealshack.co", - "serverResponseTime": 2.5712 + "serverResponseTime": 2.5478000000000005 }, { "origin": "https://events.mikescerealshack.co", - "serverResponseTime": 1.5821 + "serverResponseTime": 1.5801500000000002 }, { "origin": "https://fonts.gstatic.com", - "serverResponseTime": 0.9365 + "serverResponseTime": 0.935 } ], "sortedBy": [ @@ -18864,7 +18864,7 @@ "items": [ { "phase": "TTFB", - "timing": 602.5712, + "timing": 602.5478, "percent": "33%" }, { @@ -18874,12 +18874,12 @@ }, { "phase": "Load Time", - "timing": 234.3445723189716, + "timing": 234.45876538040773, "percent": "13%" }, { "phase": "Render Delay", - "timing": 966.0934276810284, + "timing": 966.1982346195922, "percent": "54%" } ] @@ -18968,12 +18968,12 @@ { "url": "https://www.mikescerealshack.co/_next/static/chunks/framework.9d524150d48315f49e80.js", "duration": 76, - "startTime": 907.7026 + "startTime": 907.7448999999999 }, { "url": "https://www.mikescerealshack.co/_next/static/chunks/main-1f8481d632114a408557.js", "duration": 63, - "startTime": 752.7026 + "startTime": 752.7448999999999 } ], "sortedBy": [ @@ -24175,31 +24175,31 @@ "core/lib/i18n/i18n.js | seconds": [ { "values": { - "timeInMs": 866.7026 + "timeInMs": 866.7448999999999 }, "path": "audits[first-contentful-paint].displayValue" }, { "values": { - "timeInMs": 1803.0092 + "timeInMs": 1803.2048 }, "path": "audits[largest-contentful-paint].displayValue" }, { "values": { - "timeInMs": 866.7026 + "timeInMs": 866.7448999999999 }, "path": "audits[first-meaningful-paint].displayValue" }, { "values": { - "timeInMs": 866.7026 + "timeInMs": 866.7448999999999 }, "path": "audits[speed-index].displayValue" }, { "values": { - "timeInMs": 925.2026 + "timeInMs": 925.2448999999999 }, "path": "audits.interactive.displayValue" }, @@ -24255,19 +24255,19 @@ }, { "values": { - "timeInMs": 0.0468 + "timeInMs": 0.0702 }, "path": "audits[network-rtt].displayValue" }, { "values": { - "timeInMs": 3.5377 + "timeInMs": 3.53605 }, "path": "audits[network-server-latency].displayValue" }, { "values": { - "timeInMs": 1803.0092 + "timeInMs": 1803.2048 }, "path": "audits[largest-contentful-paint-element].displayValue" } diff --git a/core/test/lib/dependency-graph/simulator/network-analyzer-test.js b/core/test/lib/dependency-graph/simulator/network-analyzer-test.js index 609d45a92322..86471a487b71 100644 --- a/core/test/lib/dependency-graph/simulator/network-analyzer-test.js +++ b/core/test/lib/dependency-graph/simulator/network-analyzer-test.js @@ -173,10 +173,21 @@ describe('DependencyGraph/Simulator/NetworkAnalyzer', () => { }); it('should infer from sendStart when available', () => { - const timing = {sendStart: 150}; + const timing = {sendStart: 100, dnsStart: -1, dnsEnd: -1}; // this record took 150ms before Chrome could send the request - // i.e. DNS (maybe) + queuing (maybe) + TCP handshake took ~100ms - // 150ms / 3 round trips ~= 50ms RTT + // i.e. queuing (maybe) + TCP handshake took ~100ms + // 100ms / 2 round trips ~= 50ms RTT + const record = createRecord({networkRequestTime: 0, networkEndTime: 1, timing}); + const result = NetworkAnalyzer.estimateRTTByOrigin([record], {coarseEstimateMultiplier: 1}); + const expected = {min: 50, max: 50, avg: 50, median: 50}; + assert.deepStrictEqual(result.get('https://example.com'), expected); + }); + + it('should infer from sendStart when available, and exclude dns', () => { + const timing = {sendStart: 150, dnsStart: 0, dnsEnd: 50}; + // this record took 150ms before Chrome could send the request + // i.e. queuing (maybe) + TCP handshake took ~100ms + // (150ms - 50ms) / 2 round trips ~= 50ms RTT const record = createRecord({networkRequestTime: 0, networkEndTime: 1, timing}); const result = NetworkAnalyzer.estimateRTTByOrigin([record], {coarseEstimateMultiplier: 1}); const expected = {min: 50, max: 50, avg: 50, median: 50}; @@ -199,7 +210,7 @@ describe('DependencyGraph/Simulator/NetworkAnalyzer', () => { }); it('should infer from TTFB when available', () => { - const timing = {receiveHeadersEnd: 1000}; + const timing = {receiveHeadersEnd: 1000, dnsStart: 0, dnsEnd: 150}; const record = createRecord({networkRequestTime: 0, networkEndTime: 1, timing, resourceType: 'Other'}); const result = NetworkAnalyzer.estimateRTTByOrigin([record], { @@ -210,6 +221,8 @@ describe('DependencyGraph/Simulator/NetworkAnalyzer', () => { // which needs ~4 RTs. We don't know its resource type so it'll be assumed that 40% of it was // server response time. // 600 ms / 4 = 150ms + // But: one of those RTs is from DNS, which we want to ignore + // (600ms - 150ms) / 3 RTs = 150ms const expected = {min: 150, max: 150, avg: 150, median: 150}; assert.deepStrictEqual(result.get('https://example.com'), expected); }); @@ -221,11 +234,11 @@ describe('DependencyGraph/Simulator/NetworkAnalyzer', () => { ]; const result = NetworkAnalyzer.estimateRTTByOrigin(records); assert.deepStrictEqual(result.get('https://example.com'), {min: 99, max: 99, avg: 99, median: 99}); - assert.deepStrictEqual(result.get('https://example2.com'), {min: 15, max: 15, avg: 15, median: 15}); + assert.deepStrictEqual(result.get('https://example2.com'), {min: 22.5, max: 22.5, avg: 22.5, median: 22.5}); }); it('should handle untrustworthy connection information', () => { - const timing = {sendStart: 150}; + const timing = {sendStart: 100}; const recordA = createRecord({networkRequestTime: 0, networkEndTime: 1, timing, connectionReused: true}); const recordB = createRecord({