From 3b3f4fb5e6f30edd55aa35165522d6b36e916d6a Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Thu, 30 Nov 2023 15:24:57 -0800 Subject: [PATCH 1/6] replace pessimistic graph with optimistic --- .../byte-efficiency/byte-efficiency-audit.js | 8 +++---- core/test/results/sample_v2.json | 24 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/audits/byte-efficiency/byte-efficiency-audit.js b/core/audits/byte-efficiency/byte-efficiency-audit.js index f7d2219fdf4b..f1c4d4011453 100644 --- a/core/audits/byte-efficiency/byte-efficiency-audit.js +++ b/core/audits/byte-efficiency/byte-efficiency-audit.js @@ -248,10 +248,10 @@ class ByteEfficiencyAudit extends Audit { if (metricComputationInput.gatherContext.gatherMode === 'navigation') { const graph = await PageDependencyGraph.request(metricComputationInput, context); const { - pessimisticGraph: pessimisticFCPGraph, + optimisticGraph: optimisticFCPGraph, } = await LanternFirstContentfulPaint.request(metricComputationInput, context); const { - pessimisticGraph: pessimisticLCPGraph, + optimisticGraph: optimisticLCPGraph, } = await LanternLargestContentfulPaint.request(metricComputationInput, context); wastedMs = this.computeWasteWithTTIGraph(results, graph, simulator, { @@ -260,13 +260,13 @@ class ByteEfficiencyAudit extends Audit { const {savings: fcpSavings} = this.computeWasteWithGraph( results, - pessimisticFCPGraph, + optimisticFCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'fcp'} ); const {savings: lcpGraphSavings} = this.computeWasteWithGraph( results, - pessimisticLCPGraph, + optimisticLCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'lcp'} ); diff --git a/core/test/results/sample_v2.json b/core/test/results/sample_v2.json index a9854feef096..5c809fa5abd2 100644 --- a/core/test/results/sample_v2.json +++ b/core/test/results/sample_v2.json @@ -4457,7 +4457,7 @@ "warnings": [], "metricSavings": { "FCP": 0, - "LCP": 300 + "LCP": 610 }, "details": { "type": "opportunity", @@ -4495,7 +4495,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 300 + "LCP": 610 } } }, @@ -4544,7 +4544,7 @@ "displayValue": "Potential savings of 64 KiB", "metricSavings": { "FCP": 0, - "LCP": 450 + "LCP": 300 }, "details": { "type": "opportunity", @@ -4598,7 +4598,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 450 + "LCP": 300 } } }, @@ -4767,7 +4767,7 @@ "displayValue": "Potential savings of 143 KiB", "metricSavings": { "FCP": 150, - "LCP": 750 + "LCP": 1060 }, "details": { "type": "opportunity", @@ -4809,7 +4809,7 @@ "type": "debugdata", "metricSavings": { "FCP": 150, - "LCP": 750 + "LCP": 1060 } } }, @@ -4851,14 +4851,14 @@ "id": "efficient-animated-content", "title": "Use video formats for animated content", "description": "Large GIFs are inefficient for delivering animated content. Consider using MPEG4/WebM videos for animations and PNG/WebP for static images instead of GIF to save network bytes. [Learn more about efficient video formats](https://developer.chrome.com/docs/lighthouse/performance/efficient-animated-content/)", - "score": 0, + "score": 0.5, "scoreDisplayMode": "metricSavings", "numericValue": 3450, "numericUnit": "millisecond", "displayValue": "Potential savings of 666 KiB", "metricSavings": { "FCP": 0, - "LCP": 3300 + "LCP": 0 }, "details": { "type": "opportunity", @@ -4895,7 +4895,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 3300 + "LCP": 0 } } }, @@ -4937,14 +4937,14 @@ "id": "legacy-javascript", "title": "Avoid serving legacy JavaScript to modern browsers", "description": "Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren't necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using module/nomodule feature detection to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to use modern JavaScript](https://web.dev/articles/publish-modern-javascript)", - "score": 0.5, + "score": 0, "scoreDisplayMode": "metricSavings", "numericValue": 450, "numericUnit": "millisecond", "displayValue": "Potential savings of 26 KiB", "metricSavings": { "FCP": 0, - "LCP": 0 + "LCP": 150 }, "details": { "type": "opportunity", @@ -5013,7 +5013,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 0 + "LCP": 150 } } }, From 9c24cf9d1362a612c4538c6656a3670dcef332ff Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Tue, 5 Dec 2023 16:52:57 -0800 Subject: [PATCH 2/6] use min of pessimistic and optimistic --- .../byte-efficiency/byte-efficiency-audit.js | 19 +++++++++++++++---- core/test/results/sample_v2.json | 14 +++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/core/audits/byte-efficiency/byte-efficiency-audit.js b/core/audits/byte-efficiency/byte-efficiency-audit.js index e551943b105c..3c418677d360 100644 --- a/core/audits/byte-efficiency/byte-efficiency-audit.js +++ b/core/audits/byte-efficiency/byte-efficiency-audit.js @@ -311,6 +311,7 @@ class ByteEfficiencyAudit extends Audit { optimisticGraph: optimisticFCPGraph, } = await LanternFirstContentfulPaint.request(metricComputationInput, context); const { + pessimisticGraph: pessimisticLCPGraph, optimisticGraph: optimisticLCPGraph, } = await LanternLargestContentfulPaint.request(metricComputationInput, context); @@ -318,19 +319,29 @@ class ByteEfficiencyAudit extends Audit { providedWastedBytesByUrl: result.wastedBytesByUrl, }); - const {savings: fcpSavings} = this.computeWasteWithGraph( + const {savings: fcpOptimisticSavings} = this.computeWasteWithGraph( results, optimisticFCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'fcp'} ); - const {savings: lcpGraphSavings} = this.computeWasteWithGraph( + const {savings: lcpOptimisticGraphSavings} = this.computeWasteWithGraph( results, optimisticLCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'lcp'} ); + const {savings: lcpPessimisticGraphSavings} = this.computeWasteWithGraph( + results, + pessimisticLCPGraph, + simulator, + {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'lcp'} + ); + + // Use the min savings between the two graphs for LCP metricSavings. + const lcpMinGraphSavings = Math.min(lcpOptimisticGraphSavings, lcpPessimisticGraphSavings); + // The LCP graph can underestimate the LCP savings if there is potential savings on the LCP record itself. let lcpRecordSavings = 0; const lcpRecord = await LCPImageRecord.request(metricComputationInput, context); @@ -341,8 +352,8 @@ class ByteEfficiencyAudit extends Audit { } } - metricSavings.FCP = fcpSavings; - metricSavings.LCP = Math.max(lcpGraphSavings, lcpRecordSavings); + metricSavings.FCP = fcpOptimisticSavings; + metricSavings.LCP = Math.max(lcpMinGraphSavings, lcpRecordSavings); } else { wastedMs = simulator.computeWastedMsFromWastedBytes(wastedBytes); } diff --git a/core/test/results/sample_v2.json b/core/test/results/sample_v2.json index 735c7e664fbb..0fc5c558706e 100644 --- a/core/test/results/sample_v2.json +++ b/core/test/results/sample_v2.json @@ -4457,7 +4457,7 @@ "warnings": [], "metricSavings": { "FCP": 0, - "LCP": 610 + "LCP": 300 }, "details": { "type": "opportunity", @@ -4495,7 +4495,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 610 + "LCP": 300 } } }, @@ -4767,7 +4767,7 @@ "displayValue": "Potential savings of 143 KiB", "metricSavings": { "FCP": 150, - "LCP": 1060 + "LCP": 750 }, "details": { "type": "opportunity", @@ -4809,7 +4809,7 @@ "type": "debugdata", "metricSavings": { "FCP": 150, - "LCP": 1060 + "LCP": 750 } } }, @@ -4937,14 +4937,14 @@ "id": "legacy-javascript", "title": "Avoid serving legacy JavaScript to modern browsers", "description": "Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren't necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using module/nomodule feature detection to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to use modern JavaScript](https://web.dev/articles/publish-modern-javascript)", - "score": 0, + "score": 0.5, "scoreDisplayMode": "metricSavings", "numericValue": 450, "numericUnit": "millisecond", "displayValue": "Potential savings of 26 KiB", "metricSavings": { "FCP": 0, - "LCP": 150 + "LCP": 0 }, "details": { "type": "opportunity", @@ -5013,7 +5013,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 150 + "LCP": 0 } } }, From 778794400dffd3893a19c0df1e738ae17dff99ec Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Thu, 7 Dec 2023 15:06:49 -0800 Subject: [PATCH 3/6] rely on the optimistic graph instead of taking the min --- .../byte-efficiency/byte-efficiency-audit.js | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/core/audits/byte-efficiency/byte-efficiency-audit.js b/core/audits/byte-efficiency/byte-efficiency-audit.js index 3c418677d360..d15685cd8cc1 100644 --- a/core/audits/byte-efficiency/byte-efficiency-audit.js +++ b/core/audits/byte-efficiency/byte-efficiency-audit.js @@ -311,7 +311,6 @@ class ByteEfficiencyAudit extends Audit { optimisticGraph: optimisticFCPGraph, } = await LanternFirstContentfulPaint.request(metricComputationInput, context); const { - pessimisticGraph: pessimisticLCPGraph, optimisticGraph: optimisticLCPGraph, } = await LanternLargestContentfulPaint.request(metricComputationInput, context); @@ -319,28 +318,19 @@ class ByteEfficiencyAudit extends Audit { providedWastedBytesByUrl: result.wastedBytesByUrl, }); - const {savings: fcpOptimisticSavings} = this.computeWasteWithGraph( + const {savings: fcpSavings} = this.computeWasteWithGraph( results, optimisticFCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'fcp'} ); - const {savings: lcpOptimisticGraphSavings} = this.computeWasteWithGraph( + const {savings: lcpSavings} = this.computeWasteWithGraph( results, optimisticLCPGraph, simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'lcp'} ); - const {savings: lcpPessimisticGraphSavings} = this.computeWasteWithGraph( - results, - pessimisticLCPGraph, - simulator, - {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'lcp'} - ); - - // Use the min savings between the two graphs for LCP metricSavings. - const lcpMinGraphSavings = Math.min(lcpOptimisticGraphSavings, lcpPessimisticGraphSavings); // The LCP graph can underestimate the LCP savings if there is potential savings on the LCP record itself. let lcpRecordSavings = 0; @@ -352,8 +342,8 @@ class ByteEfficiencyAudit extends Audit { } } - metricSavings.FCP = fcpOptimisticSavings; - metricSavings.LCP = Math.max(lcpMinGraphSavings, lcpRecordSavings); + metricSavings.FCP = fcpSavings; + metricSavings.LCP = Math.max(lcpSavings, lcpRecordSavings); } else { wastedMs = simulator.computeWastedMsFromWastedBytes(wastedBytes); } From 3c710b0b538b9723ec12dc9bf08c195129c47f6b Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Thu, 7 Dec 2023 15:07:53 -0800 Subject: [PATCH 4/6] fix --- core/test/results/sample_v2.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/test/results/sample_v2.json b/core/test/results/sample_v2.json index 0fc5c558706e..735c7e664fbb 100644 --- a/core/test/results/sample_v2.json +++ b/core/test/results/sample_v2.json @@ -4457,7 +4457,7 @@ "warnings": [], "metricSavings": { "FCP": 0, - "LCP": 300 + "LCP": 610 }, "details": { "type": "opportunity", @@ -4495,7 +4495,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 300 + "LCP": 610 } } }, @@ -4767,7 +4767,7 @@ "displayValue": "Potential savings of 143 KiB", "metricSavings": { "FCP": 150, - "LCP": 750 + "LCP": 1060 }, "details": { "type": "opportunity", @@ -4809,7 +4809,7 @@ "type": "debugdata", "metricSavings": { "FCP": 150, - "LCP": 750 + "LCP": 1060 } } }, @@ -4937,14 +4937,14 @@ "id": "legacy-javascript", "title": "Avoid serving legacy JavaScript to modern browsers", "description": "Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren't necessary for modern browsers. For your bundled JavaScript, adopt a modern script deployment strategy using module/nomodule feature detection to reduce the amount of code shipped to modern browsers, while retaining support for legacy browsers. [Learn how to use modern JavaScript](https://web.dev/articles/publish-modern-javascript)", - "score": 0.5, + "score": 0, "scoreDisplayMode": "metricSavings", "numericValue": 450, "numericUnit": "millisecond", "displayValue": "Potential savings of 26 KiB", "metricSavings": { "FCP": 0, - "LCP": 0 + "LCP": 150 }, "details": { "type": "opportunity", @@ -5013,7 +5013,7 @@ "type": "debugdata", "metricSavings": { "FCP": 0, - "LCP": 0 + "LCP": 150 } } }, From 24b39a75ef799fac6ff40a7b7ab4f30a00c99d32 Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Thu, 7 Dec 2023 15:12:25 -0800 Subject: [PATCH 5/6] note --- core/audits/byte-efficiency/byte-efficiency-audit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/core/audits/byte-efficiency/byte-efficiency-audit.js b/core/audits/byte-efficiency/byte-efficiency-audit.js index d15685cd8cc1..735cb62554df 100644 --- a/core/audits/byte-efficiency/byte-efficiency-audit.js +++ b/core/audits/byte-efficiency/byte-efficiency-audit.js @@ -324,6 +324,7 @@ class ByteEfficiencyAudit extends Audit { simulator, {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'fcp'} ); + // Note: LCP's optimistic graph sometimes unexpectedly yields higher savings than the pessimistic graph. const {savings: lcpSavings} = this.computeWasteWithGraph( results, optimisticLCPGraph, From a9464c37ed55f2ae3c83129b984b19a32d2b24dc Mon Sep 17 00:00:00 2001 From: Adriana Ixba Date: Thu, 7 Dec 2023 15:14:57 -0800 Subject: [PATCH 6/6] nit --- core/audits/byte-efficiency/byte-efficiency-audit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/audits/byte-efficiency/byte-efficiency-audit.js b/core/audits/byte-efficiency/byte-efficiency-audit.js index 735cb62554df..959aefb11ed9 100644 --- a/core/audits/byte-efficiency/byte-efficiency-audit.js +++ b/core/audits/byte-efficiency/byte-efficiency-audit.js @@ -325,7 +325,7 @@ class ByteEfficiencyAudit extends Audit { {providedWastedBytesByUrl: result.wastedBytesByUrl, label: 'fcp'} ); // Note: LCP's optimistic graph sometimes unexpectedly yields higher savings than the pessimistic graph. - const {savings: lcpSavings} = this.computeWasteWithGraph( + const {savings: lcpGraphSavings} = this.computeWasteWithGraph( results, optimisticLCPGraph, simulator, @@ -344,7 +344,7 @@ class ByteEfficiencyAudit extends Audit { } metricSavings.FCP = fcpSavings; - metricSavings.LCP = Math.max(lcpSavings, lcpRecordSavings); + metricSavings.LCP = Math.max(lcpGraphSavings, lcpRecordSavings); } else { wastedMs = simulator.computeWastedMsFromWastedBytes(wastedBytes); }