diff --git a/cli/test/smokehouse/test-definitions/dobetterweb.js b/cli/test/smokehouse/test-definitions/dobetterweb.js index cba659d2e662..90bf8371362f 100644 --- a/cli/test/smokehouse/test-definitions/dobetterweb.js +++ b/cli/test/smokehouse/test-definitions/dobetterweb.js @@ -272,22 +272,22 @@ const expectations = { details: { items: [ { - url: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=100', + url: 'http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000', }, { - url: 'http://localhost:10200/dobetterweb/unknown404.css?delay=200', + url: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&capped', }, { url: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=2200', }, { - url: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&capped', + url: 'http://localhost:10200/dobetterweb/dbw_tester.js', }, { - url: 'http://localhost:10200/dobetterweb/dbw_tester.js', + url: 'http://localhost:10200/dobetterweb/unknown404.css?delay=200', }, { - url: 'http://localhost:10200/dobetterweb/fcp-delayer.js?delay=5000', + url: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=100', }, ], }, diff --git a/core/audits/byte-efficiency/render-blocking-resources.js b/core/audits/byte-efficiency/render-blocking-resources.js index fea0d923327a..95b1034a178e 100644 --- a/core/audits/byte-efficiency/render-blocking-resources.js +++ b/core/audits/byte-efficiency/render-blocking-resources.js @@ -130,7 +130,7 @@ class RenderBlockingResources extends Audit { const wastedCssBytes = await RenderBlockingResources.computeWastedCSSBytes(artifacts, context); const navInsights = await NavigationInsights.request(trace, context); - const renderBlocking = navInsights.RenderBlocking; + const renderBlocking = navInsights.model.RenderBlocking; if (renderBlocking instanceof Error) throw renderBlocking; /** @type {LH.Audit.Context['settings']} */ diff --git a/core/computed/metrics/cumulative-layout-shift.js b/core/computed/metrics/cumulative-layout-shift.js index 50cd84f15ef6..5281664975ca 100644 --- a/core/computed/metrics/cumulative-layout-shift.js +++ b/core/computed/metrics/cumulative-layout-shift.js @@ -160,13 +160,13 @@ class CumulativeLayoutShift { Screenshots: TraceEngine.TraceHandlers.Screenshots, }); // eslint-disable-next-line max-len - await processor.parse(/** @type {import('@paulirish/trace_engine').Types.TraceEvents.TraceEventData[]} */ ( + await processor.parse(/** @type {import('@paulirish/trace_engine').Types.Events.Event[]} */ ( events - )); - if (!processor.traceParsedData) { + ), {}); + if (!processor.parsedTrace) { throw new Error('null trace engine result'); } - return processor.traceParsedData.LayoutShifts.sessionMaxScore; + return processor.parsedTrace.LayoutShifts.sessionMaxScore; }; const cumulativeLayoutShift = await run(allFrameShiftEvents.map(e => e.event)); const cumulativeLayoutShiftMainFrame = await run(mainFrameShiftEvents.map(e => e.event)); diff --git a/core/computed/metrics/lantern-metric.js b/core/computed/metrics/lantern-metric.js index f5af8a37182b..307bef465311 100644 --- a/core/computed/metrics/lantern-metric.js +++ b/core/computed/metrics/lantern-metric.js @@ -38,8 +38,10 @@ async function getComputationDataParamsFromTrace(data, context) { const graph = await PageDependencyGraph.request({...data, fromTrace: true}, context); const traceEngineResult = await TraceEngineResult.request(data, context); - const processedNavigation = - Lantern.TraceEngineComputationData.createProcessedNavigation(traceEngineResult.data); + const frameId = traceEngineResult.data.Meta.mainFrameId; + const navigationId = traceEngineResult.data.Meta.mainFrameNavigations[0].args.data.navigationId; + const processedNavigation = Lantern.TraceEngineComputationData.createProcessedNavigation( + traceEngineResult.data, frameId, navigationId); const simulator = data.simulator || (await LoadSimulator.request(data, context)); return {simulator, graph, processedNavigation}; diff --git a/core/computed/network-analysis.js b/core/computed/network-analysis.js index 78c904ae13ab..cb302e02aa36 100644 --- a/core/computed/network-analysis.js +++ b/core/computed/network-analysis.js @@ -16,7 +16,11 @@ class NetworkAnalysis { */ static async compute_(devtoolsLog, context) { const records = await NetworkRecords.request(devtoolsLog, context); - return Lantern.Core.NetworkAnalyzer.analyze(records); + const analyis = Lantern.Core.NetworkAnalyzer.analyze(records); + if (!analyis) { + throw new Error('Could not compute network analysis'); + } + return analyis; } } diff --git a/core/computed/trace-engine-result.js b/core/computed/trace-engine-result.js index 464ce46a53ac..cf26b4b95e53 100644 --- a/core/computed/trace-engine-result.js +++ b/core/computed/trace-engine-result.js @@ -30,12 +30,12 @@ class TraceEngineResult { const processor = new TraceEngine.TraceProcessor(traceHandlers); // eslint-disable-next-line max-len - await processor.parse(/** @type {import('@paulirish/trace_engine').Types.TraceEvents.TraceEventData[]} */ ( + await processor.parse(/** @type {import('@paulirish/trace_engine').Types.Events.Event[]} */ ( traceEvents - )); - if (!processor.traceParsedData) throw new Error('No data'); + ), {}); + if (!processor.parsedTrace) throw new Error('No data'); if (!processor.insights) throw new Error('No insights'); - return {data: processor.traceParsedData, insights: processor.insights}; + return {data: processor.parsedTrace, insights: processor.insights}; } /** diff --git a/core/lib/trace-engine.js b/core/lib/trace-engine.js index 0914a9c14b52..b000c6bfcca2 100644 --- a/core/lib/trace-engine.js +++ b/core/lib/trace-engine.js @@ -2,7 +2,7 @@ import * as TraceEngine from '@paulirish/trace_engine'; import {polyfillDOMRect} from './polyfill-dom-rect.js'; -/** @typedef {import('@paulirish/trace_engine').Types.TraceEvents.SyntheticLayoutShift} SyntheticLayoutShift */ +/** @typedef {import('@paulirish/trace_engine').Types.Events.SyntheticLayoutShift} SyntheticLayoutShift */ /** @typedef {SyntheticLayoutShift & {args: {data: NonNullable}}} SaneSyntheticLayoutShift */ polyfillDOMRect(); diff --git a/core/test/audits/dobetterweb/dom-size-test.js b/core/test/audits/dobetterweb/dom-size-test.js index ba68bef5cc4c..09e76ed0f33e 100644 --- a/core/test/audits/dobetterweb/dom-size-test.js +++ b/core/test/audits/dobetterweb/dom-size-test.js @@ -18,7 +18,7 @@ describe('DOMSize audit', () => { beforeEach(() => { const mainDocumentUrl = 'https://example.com/'; - const networkRecords = [{url: mainDocumentUrl, priority: 'High'}]; + const networkRecords = [{url: mainDocumentUrl, priority: 'High', transferSize: 1000}]; const trace = createTestTrace({ largestContentfulPaint: 15, topLevelTasks: [ diff --git a/core/test/audits/dobetterweb/uses-http2-test.js b/core/test/audits/dobetterweb/uses-http2-test.js index 082d58c40b6f..342a92cabaa6 100644 --- a/core/test/audits/dobetterweb/uses-http2-test.js +++ b/core/test/audits/dobetterweb/uses-http2-test.js @@ -43,31 +43,37 @@ describe('Resources are fetched over http/2', () => { it('should pass when resources are requested via http/2', async () => { const networkRecords = [{ url: 'https://www.example.com/', + transferSize: 1000, priority: 'High', protocol: 'h2', }, { url: 'https://www.example.com/2', + transferSize: 1000, priority: 'High', protocol: 'h2', }, { url: 'https://www.example.com/3', + transferSize: 1000, priority: 'High', protocol: 'h2', }, { url: 'https://www.example.com/4', + transferSize: 1000, priority: 'High', protocol: 'h2', }, { url: 'https://www.example.com/5', + transferSize: 1000, priority: 'High', protocol: 'h2', }, { url: 'https://www.example.com/6', + transferSize: 1000, priority: 'High', protocol: 'h2', }, @@ -267,36 +273,43 @@ describe('Resources are fetched over http/2', () => { const networkRecords = [ { url: 'https://www.twitter.com/', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.twitter.com/2', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.twitter.com/3', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.twitter.com/4', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.twitter.com/5', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.twitter.com/embed/foo', + transferSize: 1000, priority: 'High', protocol: 'HTTP/1.1', }, { url: 'https://www.facebook.com/embed', + transferSize: 1000, protocol: 'HTTP/1.1', priority: 'High', }, diff --git a/core/test/audits/long-tasks-test.js b/core/test/audits/long-tasks-test.js index 0f21dd2228c5..16276253ede5 100644 --- a/core/test/audits/long-tasks-test.js +++ b/core/test/audits/long-tasks-test.js @@ -152,6 +152,7 @@ describe('Long tasks audit', () => { url: TASK_URL, priority: 'High', timing: {connectEnd: 50, connectStart: 0.01, sslStart: 25, sslEnd: 40}, + transferSize: 1000, }]; const artifacts = { diff --git a/core/test/audits/redirects-test.js b/core/test/audits/redirects-test.js index 7c33488c8c5c..6ac017e70bbc 100644 --- a/core/test/audits/redirects-test.js +++ b/core/test/audits/redirects-test.js @@ -34,6 +34,7 @@ const FAILING_THREE_REDIRECTS = [{ priority: 'VeryHigh', url: 'https://m.example.com/final', timing: {receiveHeadersEnd: 19}, + transferSize: 1000, }]; const FAILING_TWO_REDIRECTS = [{ @@ -54,6 +55,7 @@ const FAILING_TWO_REDIRECTS = [{ priority: 'VeryHigh', url: 'https://www.lisairish.com/', timing: {receiveHeadersEnd: 448}, + transferSize: 1000, }]; const SUCCESS_ONE_REDIRECT = [{ @@ -68,6 +70,7 @@ const SUCCESS_ONE_REDIRECT = [{ priority: 'VeryHigh', url: 'https://www.lisairish.com/', timing: {receiveHeadersEnd: 139}, + transferSize: 1000, }]; const SUCCESS_NOREDIRECT = [{ @@ -76,6 +79,7 @@ const SUCCESS_NOREDIRECT = [{ priority: 'VeryHigh', url: 'https://www.google.com/', timing: {receiveHeadersEnd: 140}, + transferSize: 1000, }]; const FAILING_CLIENTSIDE = [ @@ -92,6 +96,7 @@ const FAILING_CLIENTSIDE = [ priority: 'VeryHigh', url: 'https://lisairish.com/', timing: {receiveHeadersEnd: 447}, + transferSize: 1000, }, { requestId: '2', @@ -99,6 +104,7 @@ const FAILING_CLIENTSIDE = [ priority: 'VeryHigh', url: 'https://www.lisairish.com/', timing: {receiveHeadersEnd: 448}, + transferSize: 1000, }, ]; @@ -108,6 +114,7 @@ const FAILING_SELF_REDIRECT = [{ priority: 'VeryHigh', networkRequestTime: 0, responseHeadersEndTime: 500, + transferSize: 1000, }, { requestId: '2', @@ -115,6 +122,7 @@ const FAILING_SELF_REDIRECT = [{ priority: 'VeryHigh', networkRequestTime: 1000, responseHeadersEndTime: 1500, + transferSize: 1000, }, { requestId: '3', @@ -122,6 +130,7 @@ const FAILING_SELF_REDIRECT = [{ priority: 'VeryHigh', networkRequestTime: 3000, responseHeadersEndTime: 3500, + transferSize: 1000, }]; describe('Performance: Redirects audit', () => { diff --git a/core/test/audits/uses-rel-preconnect-test.js b/core/test/audits/uses-rel-preconnect-test.js index c1808b5c7e2d..776e9b5835ee 100644 --- a/core/test/audits/uses-rel-preconnect-test.js +++ b/core/test/audits/uses-rel-preconnect-test.js @@ -18,6 +18,10 @@ const mainResource = { }; function buildArtifacts(networkRecords, fcpTs) { + for (const record of networkRecords) { + record.transferSize = record.transferSize ?? 1000; + } + const trace = createTestTrace({ timeOrigin: 0, largestContentfulPaint: 5000, diff --git a/core/test/audits/uses-rel-preload-test.js b/core/test/audits/uses-rel-preload-test.js index 2e43cb87ca41..c9f9989b47e1 100644 --- a/core/test/audits/uses-rel-preload-test.js +++ b/core/test/audits/uses-rel-preload-test.js @@ -51,6 +51,7 @@ describe('Performance: uses-rel-preload audit', () => { { requestId: '2', networkRequestTime: 10_000, + transferSize: 1000, isLinkPreload: false, url: secondRecordUrl, timing: defaultMainResource.timing, @@ -63,6 +64,7 @@ describe('Performance: uses-rel-preload audit', () => { // Normally this request would be flagged for preloading. requestId: '3', networkRequestTime: 20_000, + transferSize: 1000, isLinkPreload: false, url: 'http://www.example.com/a-different-script.js', timing: defaultMainResource.timing, @@ -100,6 +102,7 @@ describe('Performance: uses-rel-preload audit', () => { isLinkPreload: false, networkRequestTime: 500, networkEndTime: 1000, + transferSize: 1000, timing: {receiveHeadersEnd: 500}, url: mainDocumentNodeUrl, }, @@ -110,6 +113,7 @@ describe('Performance: uses-rel-preload audit', () => { isLinkPreload: false, networkRequestTime: 1000, networkEndTime: 2000, + transferSize: 1000, timing: {receiveHeadersEnd: 1000}, url: scriptNodeUrl, initiator: {type: 'parser', url: mainDocumentNodeUrl}, @@ -121,6 +125,7 @@ describe('Performance: uses-rel-preload audit', () => { isLinkPreload: false, networkRequestTime: 2000, networkEndTime: 3_250, + transferSize: 1000, timing: {receiveHeadersEnd: 1250}, url: scriptAddedNodeUrl, initiator: {type: 'script', url: scriptNodeUrl}, @@ -132,6 +137,7 @@ describe('Performance: uses-rel-preload audit', () => { isLinkPreload: false, networkRequestTime: 2000, networkEndTime: 3000, + transferSize: 1000, timing: {receiveHeadersEnd: 1000}, url: scriptSubNodeUrl, initiator: {type: 'script', url: scriptNodeUrl}, @@ -143,6 +149,7 @@ describe('Performance: uses-rel-preload audit', () => { isLinkPreload: false, networkRequestTime: 2000, networkEndTime: 3_500, + transferSize: 1000, timing: {receiveHeadersEnd: 1500}, url: scriptOtherNodeUrl, initiator: {type: 'script', url: scriptNodeUrl}, @@ -170,7 +177,7 @@ describe('Performance: uses-rel-preload audit', () => { const artifacts = mockArtifacts(networkRecords, defaultMainResourceUrl); const context = {settings: {}, computedCache: new Map()}; return UsesRelPreload.audit(artifacts, context).then(output => { - assert.equal(output.details.overallSavingsMs, 314); + assert.equal(output.details.overallSavingsMs, 303); assert.equal(output.details.items.length, 1); }); }); diff --git a/core/test/computed/load-simulator-test.js b/core/test/computed/load-simulator-test.js index a6a46f2224a1..44250ba00b95 100644 --- a/core/test/computed/load-simulator-test.js +++ b/core/test/computed/load-simulator-test.js @@ -32,9 +32,9 @@ describe('Simulator artifact', () => { }, context); assert.equal(Math.round(simulator._rtt), 3); - assert.equal(Math.round(simulator._throughput / 1024), 1590); - assert.equal(simulator._cpuSlowdownMultiplier, 1); - assert.equal(simulator._layoutTaskMultiplier, 1); + assert.equal(Math.round(simulator.throughput / 1024), 1590); + assert.equal(simulator.cpuSlowdownMultiplier, 1); + assert.equal(simulator.layoutTaskMultiplier, 1); }); it('returns a simulator for "devtools" throttling', async () => { @@ -47,9 +47,9 @@ describe('Simulator artifact', () => { }, context); assert.equal(simulator._rtt, 100); - assert.equal(simulator._throughput / 1024, 1000); - assert.equal(simulator._cpuSlowdownMultiplier, 1); - assert.equal(simulator._layoutTaskMultiplier, 1); + assert.equal(simulator.throughput / 1024, 1000); + assert.equal(simulator.cpuSlowdownMultiplier, 1); + assert.equal(simulator.layoutTaskMultiplier, 1); }); it('returns a simulator for "simulate" throttling', async () => { @@ -59,12 +59,12 @@ describe('Simulator artifact', () => { const simulator = await LoadSimulator.request({devtoolsLog, settings}, context); assert.equal(simulator._rtt, 120); - assert.equal(simulator._throughput / 1024, 1000); - assert.equal(simulator._cpuSlowdownMultiplier, 3); - assert.equal(simulator._layoutTaskMultiplier, 1.5); + assert.equal(simulator.throughput / 1024, 1000); + assert.equal(simulator.cpuSlowdownMultiplier, 3); + assert.equal(simulator.layoutTaskMultiplier, 1.5); simulator.simulate(createNetworkNode()); - const {additionalRttByOrigin, serverResponseTimeByOrigin} = simulator._connectionPool._options; + const {additionalRttByOrigin, serverResponseTimeByOrigin} = simulator.connectionPool.options; expect(additionalRttByOrigin.get('https://pwa.rocks')).toMatchInlineSnapshot( `0.3960000176447025` ); @@ -90,7 +90,7 @@ describe('Simulator artifact', () => { const simulator = await LoadSimulator.request({devtoolsLog, settings}, context); const result = simulator.simulate(createNetworkNode()); - const {additionalRttByOrigin, serverResponseTimeByOrigin} = simulator._connectionPool._options; + const {additionalRttByOrigin, serverResponseTimeByOrigin} = simulator.connectionPool.options; // Make sure we passed through the right RTT expect(additionalRttByOrigin).toEqual(new Map([ ['https://pwa.rocks', 1000], diff --git a/core/test/computed/metrics/lcp-breakdown-test.js b/core/test/computed/metrics/lcp-breakdown-test.js index 62087e09fe30..42516a1979f8 100644 --- a/core/test/computed/metrics/lcp-breakdown-test.js +++ b/core/test/computed/metrics/lcp-breakdown-test.js @@ -104,8 +104,8 @@ describe('LCPBreakdown', () => { const result = await LCPBreakdown.request(data, {computedCache: new Map()}); expect(result.ttfb).toBeCloseTo(1245.5, 0.1); - expect(result.loadStart).toBeCloseTo(3523.3, 0.1); - expect(result.loadEnd).toBeCloseTo(3917.6, 0.1); + expect(result.loadStart).toBeCloseTo(3558.6, 0.1); + expect(result.loadEnd).toBeCloseTo(3956.8, 0.1); }); it('returns breakdown for a real trace with text LCP', async () => { diff --git a/core/test/computed/tbt-impact-tasks-test.js b/core/test/computed/tbt-impact-tasks-test.js index 3a2d9c8c79d1..ed5a97216eb1 100644 --- a/core/test/computed/tbt-impact-tasks-test.js +++ b/core/test/computed/tbt-impact-tasks-test.js @@ -260,7 +260,7 @@ describe('TBTImpactTasks', () => { expect(tasksWithNoChildren).toEqual(tasksWithAllSelfImpact); const totalSelfImpact = tasksImpactingTbt.reduce((sum, t) => sum += t.selfTbtImpact, 0); - expect(totalSelfImpact).toMatchInlineSnapshot(`2819.9999999999577`); + expect(totalSelfImpact).toMatchInlineSnapshot(`2819.9999999999545`); // Total self blocking time is just the total self impact without factoring in the TBT // bounds, so it should always be greater than or equal to the total TBT self impact. diff --git a/package.json b/package.json index 5bbad85e1dd8..21c0f4d0fb03 100644 --- a/package.json +++ b/package.json @@ -181,7 +181,7 @@ "webtreemap-cdt": "^3.2.1" }, "dependencies": { - "@paulirish/trace_engine": "0.0.32", + "@paulirish/trace_engine": "0.0.38", "@sentry/node": "^7.0.0", "axe-core": "^4.10.2", "chrome-launcher": "^1.1.2", diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts index 0abf2c060887..19ae925055fa 100644 --- a/types/artifacts.d.ts +++ b/types/artifacts.d.ts @@ -510,8 +510,8 @@ declare module Artifacts { } interface TraceEngineResult { - data: TraceEngine.Handlers.Types.TraceParseData; - insights: TraceEngine.Insights.Types.TraceInsightData; + data: TraceEngine.Handlers.Types.ParsedTrace; + insights: TraceEngine.Insights.Types.TraceInsightSets; } interface TraceEngineRootCauses { diff --git a/yarn.lock b/yarn.lock index 79d6c3f0b727..b58491d6769a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1080,10 +1080,12 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@paulirish/trace_engine@0.0.32": - version "0.0.32" - resolved "https://registry.yarnpkg.com/@paulirish/trace_engine/-/trace_engine-0.0.32.tgz#090fd603f9264aad6fce4461574693b1462f799f" - integrity sha512-KxWFdRNbv13U8bhYaQvH6gLG9CVEt2jKeosyOOYILVntWEVWhovbgDrbOiZ12pJO3vjZs0Zgbd3/Zgde98woEA== +"@paulirish/trace_engine@0.0.38": + version "0.0.38" + resolved "https://registry.yarnpkg.com/@paulirish/trace_engine/-/trace_engine-0.0.38.tgz#e9bd1d792b62d7bb656c5b0efa4bdf4b072a509c" + integrity sha512-8wCP9KFeXOZ/9bm3IoGibQ49gbNdwIGXxGUaDVyXDY4v08MiMyUtb+qInrERGgT8i0yGBDayR7wcCfqAaosVaA== + dependencies: + third-party-web latest "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" @@ -6947,6 +6949,11 @@ third-party-web@^0.26.1: resolved "https://registry.yarnpkg.com/third-party-web/-/third-party-web-0.26.1.tgz#1d5051777396eccc4fc0e2675b43861725eaa494" integrity sha512-I5Y7YT4841769UjrAcy/c0G/Bb/4lqBzA7LHzx17z5rxE7zzNhf4gpOME3hK3oktZc36oZQpskUG2UXGrUAECA== +third-party-web@latest: + version "0.26.2" + resolved "https://registry.yarnpkg.com/third-party-web/-/third-party-web-0.26.2.tgz#9fe6ba32cc851bb35a9d540f44c7fa358c57867c" + integrity sha512-taJ0Us0lKoYBqcbccMuDElSUPOxmBfwlHe1OkHQ3KFf+RwovvBHdXhbFk9XJVQE2vHzxbTwvwg5GFsT9hbDokQ== + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"