From 5b9360bdfb9558f7a1c356b304b549d468e42ae6 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 01:01:33 +0200 Subject: [PATCH 01/12] insights mapping --- definitions/output/reports/tech_crux.js | 48 +++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index b607bf6f..a6511655 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -42,12 +42,54 @@ const results = [] for (const category of Object.keys(lighthouse?.categories ? lighthouse.categories : {})) { for (const audit of lighthouse.categories[category].auditRefs) { if ( - lighthouse.audits[audit.id].score === 1 && - !['metrics', 'hidden'].includes(audit.group) + lighthouse.audits[audit.id].score === 1 // Only include audits that passed + && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits + && ![ + 'first-meaningful-paint', + 'no-document-write', + 'offscreen-images', + 'uses-passive-event-listeners', + 'uses-rel-preload', + 'third-party-facades' + ].includes(audit.id) // Add any specific audits to exclude here ) { + + // Map old audit IDs to new insight audit IDs + const auditIdMapping = { + 'layout-shifts': 'cls-culprits-insight', + 'non-composited-animations': 'cls-culprits-insight', + 'unsized-images': 'cls-culprits-insight', + 'redirects': 'document-latency-insight', + 'server-response-time': 'document-latency-insight', + 'uses-text-compression': 'document-latency-insight', + 'dom-size': 'dom-size-insight', + 'duplicated-javascript': 'duplicated-javascript-insight', + 'font-display': 'font-display-insight', + 'modern-image-formats': 'image-delivery-insight', + 'uses-optimized-images': 'image-delivery-insight', + 'efficient-animated-content': 'image-delivery-insight', + 'uses-responsive-images': 'image-delivery-insight', + 'work-during-interaction': 'interaction-to-next-paint-insight', + 'prioritize-lcp-image': 'lcp-discovery-insight', + 'lcp-lazy-loaded': 'lcp-discovery-insight', + 'largest-contentful-paint-element': 'lcp-phases-insight', + 'legacy-javascript': 'legacy-javascript-insight', + 'uses-http2': 'modern-http-insight', + 'critical-request-chains': 'network-dependency-tree-insight', + 'uses-rel-preconnect': 'network-dependency-tree-insight', + 'render-blocking-resources': 'render-blocking-insight', + 'third-party-summary': 'third-parties-insight', + 'uses-long-cache-ttl': 'use-cache-insight', + 'viewport': 'viewport-insight' + }; + + // Use mapped audit ID if available, otherwise use original + const mappedAuditId = auditIdMapping[audit.id] || audit.id; + + // Push the audit with the category and mapped ID results.push({ category, - id: audit.id + id: mappedAuditId }) } } From 8f2533fcb9de73998f56e0db5741de789a358c70 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:05:33 +0200 Subject: [PATCH 02/12] optimised performance insights --- definitions/output/reports/tech_crux.js | 151 ++++++++++++------------ 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index a6511655..8491bd04 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -41,56 +41,72 @@ const results = [] for (const category of Object.keys(lighthouse?.categories ? lighthouse.categories : {})) { for (const audit of lighthouse.categories[category].auditRefs) { - if ( - lighthouse.audits[audit.id].score === 1 // Only include audits that passed - && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits - && ![ + + // Moving lighthouse to insights https://developer.chrome.com/blog/moving-lighthouse-to-insights + if (category === 'performance' && ${pastMonth} < '2025-10-01') { + if ( + [ 'first-meaningful-paint', 'no-document-write', 'offscreen-images', 'uses-passive-event-listeners', 'uses-rel-preload', 'third-party-facades' - ].includes(audit.id) // Add any specific audits to exclude here - ) { + ].includes(audit.id) + ) { + continue; // Deprecated audits + } else if ( + lighthouse.audits[audit.id].score === 1 // Only include audits that passed + && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits + ) { + // Map old audit IDs to new insight audit IDs + const performanceAuditIdMapping = { + 'layout-shifts': 'cls-culprits-insight', + 'non-composited-animations': 'cls-culprits-insight', + 'unsized-images': 'cls-culprits-insight', + 'redirects': 'document-latency-insight', + 'server-response-time': 'document-latency-insight', + 'uses-text-compression': 'document-latency-insight', + 'dom-size': 'dom-size-insight', + 'duplicated-javascript': 'duplicated-javascript-insight', + 'font-display': 'font-display-insight', + 'modern-image-formats': 'image-delivery-insight', + 'uses-optimized-images': 'image-delivery-insight', + 'efficient-animated-content': 'image-delivery-insight', + 'uses-responsive-images': 'image-delivery-insight', + 'work-during-interaction': 'interaction-to-next-paint-insight', + 'prioritize-lcp-image': 'lcp-discovery-insight', + 'lcp-lazy-loaded': 'lcp-discovery-insight', + 'largest-contentful-paint-element': 'lcp-phases-insight', + 'legacy-javascript': 'legacy-javascript-insight', + 'uses-http2': 'modern-http-insight', + 'critical-request-chains': 'network-dependency-tree-insight', + 'uses-rel-preconnect': 'network-dependency-tree-insight', + 'render-blocking-resources': 'render-blocking-insight', + 'third-party-summary': 'third-parties-insight', + 'uses-long-cache-ttl': 'use-cache-insight', + 'viewport': 'viewport-insight' + }; + + // Use mapped audit ID if available, otherwise use original + const mappedAuditId = performanceAuditIdMapping[audit.id] || audit.id; + + // Push the audit with the category and mapped ID + results.push({ + category, + id: mappedAuditId + }); + } + } - // Map old audit IDs to new insight audit IDs - const auditIdMapping = { - 'layout-shifts': 'cls-culprits-insight', - 'non-composited-animations': 'cls-culprits-insight', - 'unsized-images': 'cls-culprits-insight', - 'redirects': 'document-latency-insight', - 'server-response-time': 'document-latency-insight', - 'uses-text-compression': 'document-latency-insight', - 'dom-size': 'dom-size-insight', - 'duplicated-javascript': 'duplicated-javascript-insight', - 'font-display': 'font-display-insight', - 'modern-image-formats': 'image-delivery-insight', - 'uses-optimized-images': 'image-delivery-insight', - 'efficient-animated-content': 'image-delivery-insight', - 'uses-responsive-images': 'image-delivery-insight', - 'work-during-interaction': 'interaction-to-next-paint-insight', - 'prioritize-lcp-image': 'lcp-discovery-insight', - 'lcp-lazy-loaded': 'lcp-discovery-insight', - 'largest-contentful-paint-element': 'lcp-phases-insight', - 'legacy-javascript': 'legacy-javascript-insight', - 'uses-http2': 'modern-http-insight', - 'critical-request-chains': 'network-dependency-tree-insight', - 'uses-rel-preconnect': 'network-dependency-tree-insight', - 'render-blocking-resources': 'render-blocking-insight', - 'third-party-summary': 'third-parties-insight', - 'uses-long-cache-ttl': 'use-cache-insight', - 'viewport': 'viewport-insight' - }; - - // Use mapped audit ID if available, otherwise use original - const mappedAuditId = auditIdMapping[audit.id] || audit.id; - - // Push the audit with the category and mapped ID + if ( + lighthouse.audits[audit.id].score === 1 // Only include audits that passed + && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits + ) { results.push({ category, - id: mappedAuditId - }) + id: audit.id + }); } } } @@ -252,16 +268,24 @@ technologies AS ( lab_data AS ( SELECT client, - page, root_page, - SAFE.INT64(summary.bytesTotal) AS bytesTotal, - SAFE.INT64(summary.bytesJS) AS bytesJS, - SAFE.INT64(summary.bytesImg) AS bytesImg, - SAFE.FLOAT64(lighthouse.categories.accessibility.score) AS accessibility, - SAFE.FLOAT64(lighthouse.categories['best-practices'].score) AS best_practices, - SAFE.FLOAT64(lighthouse.categories.performance.score) AS performance, - SAFE.FLOAT64(lighthouse.categories.seo.score) AS seo + technology, + version, + AVG(SAFE.INT64(summary.bytesTotal)) AS bytesTotal, + AVG(SAFE.INT64(summary.bytesJS)) AS bytesJS, + AVG(SAFE.INT64(summary.bytesImg)) AS bytesImg, + AVG(SAFE.FLOAT64(lighthouse.categories.accessibility.score)) AS accessibility, + AVG(SAFE.FLOAT64(lighthouse.categories['best-practices'].score)) AS best_practices, + AVG(SAFE.FLOAT64(lighthouse.categories.performance.score)) AS performance, + AVG(SAFE.FLOAT64(lighthouse.categories.seo.score)) AS seo FROM pages + INNER JOIN technologies + USING (client, page) + GROUP BY + client, + root_page, + technology, + version ), audits AS ( @@ -273,7 +297,7 @@ audits AS ( audit_category, audit_id FROM ( - SELECT + SELECT DISTINCT client, page, root_page, @@ -286,29 +310,6 @@ audits AS ( USING (client, page) ), -lab_metrics AS ( - SELECT - client, - root_page, - technology, - version, - AVG(bytesTotal) AS bytesTotal, - AVG(bytesJS) AS bytesJS, - AVG(bytesImg) AS bytesImg, - AVG(accessibility) AS accessibility, - AVG(best_practices) AS best_practices, - AVG(performance) AS performance, - AVG(seo) AS seo - FROM lab_data - INNER JOIN technologies - USING (client, page) - GROUP BY - client, - root_page, - technology, - version -), - origins_summary AS ( SELECT geo, @@ -317,7 +318,7 @@ origins_summary AS ( technology, version, COUNT(DISTINCT root_page) AS origins - FROM lab_metrics + FROM lab_data INNER JOIN crux USING (client, root_page) GROUP BY @@ -413,7 +414,7 @@ other_summary AS ( SAFE_CAST(APPROX_QUANTILES(bytesImg, 1000)[OFFSET(500)] AS INT64) AS images ) AS median_page_weight_bytes - FROM lab_metrics + FROM lab_data INNER JOIN crux USING (client, root_page) GROUP BY From f705ea0ffdcb30fcc70f2e5c86b858c696362c50 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:35:50 +0200 Subject: [PATCH 03/12] some optimizations --- definitions/output/reports/tech_crux.js | 153 +++++++++++------------- 1 file changed, 72 insertions(+), 81 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 8491bd04..2379523a 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -188,17 +188,17 @@ geo_summary AS ( device IN ('desktop', 'phone') ), -crux AS ( +base_crux AS ( SELECT geo, - CASE _rank - WHEN 100000000 THEN 'ALL' - WHEN 10000000 THEN 'Top 10M' - WHEN 1000000 THEN 'Top 1M' - WHEN 100000 THEN 'Top 100k' - WHEN 10000 THEN 'Top 10k' - WHEN 1000 THEN 'Top 1k' - END AS rank, + CASE + WHEN rank <= 1000 THEN ['Top 1k', 'Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 10000 THEN ['Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 100000 THEN ['Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 1000000 THEN ['Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 10000000 THEN ['Top 10M', 'ALL'] + ELSE ['Unknown'] + END AS eligible_ranks, CONCAT(origin, '/') AS root_page, IF(device = 'desktop', 'desktop', 'mobile') AS client, @@ -225,9 +225,32 @@ crux AS ( IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb) AS good_ttfb, IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp, IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp - FROM geo_summary, - UNNEST([1000, 10000, 100000, 1000000, 10000000, 100000000]) AS _rank - WHERE rank <= _rank + FROM geo_summary +), + +crux AS ( + SELECT + geo, + rank, + root_page, + client, + + any_fid, + good_fid, + any_cls, + good_cls, + any_lcp, + good_lcp, + good_cwv, + + any_fcp, + good_fcp, + any_ttfb, + good_ttfb, + any_inp, + good_inp + FROM base_crux, + UNNEST(eligible_ranks) AS rank ), technologies AS ( @@ -289,93 +312,40 @@ lab_data AS ( ), audits AS ( - SELECT DISTINCT + SELECT + geo, client, - root_page, + rank, technology, version, - audit_category, - audit_id + category, + id, + COUNT(DISTINCT root_page) AS origins FROM ( SELECT DISTINCT client, page, root_page, - audits.category AS audit_category, - audits.id AS audit_id + audits.category, + audits.id FROM pages INNER JOIN UNNEST(get_passed_audits(pages.lighthouse)) AS audits ) AS audits_data INNER JOIN technologies USING (client, page) -), - -origins_summary AS ( - SELECT - geo, - client, - rank, - technology, - version, - COUNT(DISTINCT root_page) AS origins - FROM lab_data INNER JOIN crux USING (client, root_page) GROUP BY - geo, - client, - rank, - technology, - version - -), - - -audits_summary AS ( - SELECT geo, client, rank, technology, version, - ARRAY_AGG(STRUCT( - audit_category AS category, - audit_id AS id, - SAFE_DIVIDE(audits.origins, origins_summary.origins) AS pass_rate - )) AS audits - FROM ( - SELECT - geo, - client, - rank, - technology, - version, - audit_category, - audit_id, - COUNT(DISTINCT root_page) AS origins - FROM audits - INNER JOIN crux - USING (client, root_page) - GROUP BY - geo, - client, - rank, - technology, - version, - audit_category, - audit_id - ) AS audits - LEFT JOIN origins_summary - USING (geo, client, rank, technology, version) - GROUP BY - geo, - client, - rank, - technology, - version + category, + id ), -other_summary AS ( +base_summary AS ( SELECT geo, client, @@ -412,8 +382,9 @@ other_summary AS ( SAFE_CAST(APPROX_QUANTILES(bytesTotal, 1000)[OFFSET(500)] AS INT64) AS total, SAFE_CAST(APPROX_QUANTILES(bytesJS, 1000)[OFFSET(500)] AS INT64) AS js, SAFE_CAST(APPROX_QUANTILES(bytesImg, 1000)[OFFSET(500)] AS INT64) AS images - ) AS median_page_weight_bytes + ) AS median_page_weight_bytes, + COUNT(DISTINCT root_page) AS origins FROM lab_data INNER JOIN crux USING (client, root_page) @@ -423,6 +394,29 @@ other_summary AS ( rank, technology, version +), + +audits_summary AS ( + SELECT + geo, + client, + rank, + technology, + version, + ARRAY_AGG(STRUCT( + category AS category, + id AS id, + SAFE_DIVIDE(audits.origins, base_summary.origins) AS pass_rate + )) AS audits + FROM audits + LEFT JOIN base_summary + USING (geo, client, rank, technology, version) + GROUP BY + geo, + client, + rank, + technology, + version ) SELECT @@ -433,15 +427,12 @@ SELECT technology, version, - # Metrics origins, crux, median_lighthouse_score, median_page_weight_bytes, audits -FROM origins_summary -LEFT JOIN other_summary -USING (geo, client, rank, technology, version) +FROM base_summary LEFT JOIN audits_summary USING (geo, client, rank, technology, version) `) From da264f7cd819dd90b8a20d11c8296d2a2e9b417c Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:47:32 +0200 Subject: [PATCH 04/12] fix --- definitions/output/reports/tech_crux.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 2379523a..f00b476a 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -43,7 +43,7 @@ for (const category of Object.keys(lighthouse?.categories ? lighthouse.categorie for (const audit of lighthouse.categories[category].auditRefs) { // Moving lighthouse to insights https://developer.chrome.com/blog/moving-lighthouse-to-insights - if (category === 'performance' && ${pastMonth} < '2025-10-01') { + if (category === 'performance' && '${pastMonth}' < '2025-10-01') { if ( [ 'first-meaningful-paint', From 3889478d554c304199fc4e82de47562a55e1c3ed Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:50:35 +0200 Subject: [PATCH 05/12] fix rank --- definitions/output/reports/tech_crux.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index f00b476a..0809630c 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -197,7 +197,7 @@ base_crux AS ( WHEN rank <= 100000 THEN ['Top 100k', 'Top 1M', 'Top 10M', 'ALL'] WHEN rank <= 1000000 THEN ['Top 1M', 'Top 10M', 'ALL'] WHEN rank <= 10000000 THEN ['Top 10M', 'ALL'] - ELSE ['Unknown'] + WHEN rank <= 100000000 THEN ['ALL'] END AS eligible_ranks, CONCAT(origin, '/') AS root_page, IF(device = 'desktop', 'desktop', 'mobile') AS client, From ff9629948a9bae021578b9030d67bf2da61208f4 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 04:03:31 +0200 Subject: [PATCH 06/12] fmt --- definitions/output/reports/tech_crux.js | 80 ++++++++++++------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 0809630c..8822a121 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -188,46 +188,6 @@ geo_summary AS ( device IN ('desktop', 'phone') ), -base_crux AS ( - SELECT - geo, - CASE - WHEN rank <= 1000 THEN ['Top 1k', 'Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] - WHEN rank <= 10000 THEN ['Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] - WHEN rank <= 100000 THEN ['Top 100k', 'Top 1M', 'Top 10M', 'ALL'] - WHEN rank <= 1000000 THEN ['Top 1M', 'Top 10M', 'ALL'] - WHEN rank <= 10000000 THEN ['Top 10M', 'ALL'] - WHEN rank <= 100000000 THEN ['ALL'] - END AS eligible_ranks, - CONCAT(origin, '/') AS root_page, - IF(device = 'desktop', 'desktop', 'mobile') AS client, - - # CWV - IS_NON_ZERO(fast_fid, avg_fid, slow_fid) AS any_fid, - IS_GOOD(fast_fid, avg_fid, slow_fid) AS good_fid, - IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls, - IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls, - IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp, - IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp, - IF('${pastMonth}' < '2024-01-01', - (IS_GOOD(fast_fid, avg_fid, slow_fid) OR fast_fid IS NULL) AND - IS_GOOD(small_cls, medium_cls, large_cls) AND - IS_GOOD(fast_lcp, avg_lcp, slow_lcp), - (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND - IS_GOOD(small_cls, medium_cls, large_cls) AND - IS_GOOD(fast_lcp, avg_lcp, slow_lcp) - ) AS good_cwv, - - # WV - IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp) AS any_fcp, - IS_GOOD(fast_fcp, avg_fcp, slow_fcp) AS good_fcp, - IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb) AS any_ttfb, - IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb) AS good_ttfb, - IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp, - IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp - FROM geo_summary -), - crux AS ( SELECT geo, @@ -249,7 +209,45 @@ crux AS ( good_ttfb, any_inp, good_inp - FROM base_crux, + FROM ( + SELECT + geo, + CASE + WHEN rank <= 1000 THEN ['Top 1k', 'Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 10000 THEN ['Top 10k', 'Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 100000 THEN ['Top 100k', 'Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 1000000 THEN ['Top 1M', 'Top 10M', 'ALL'] + WHEN rank <= 10000000 THEN ['Top 10M', 'ALL'] + WHEN rank <= 100000000 THEN ['ALL'] + END AS eligible_ranks, + CONCAT(origin, '/') AS root_page, + IF(device = 'desktop', 'desktop', 'mobile') AS client, + + # CWV + IS_NON_ZERO(fast_fid, avg_fid, slow_fid) AS any_fid, + IS_GOOD(fast_fid, avg_fid, slow_fid) AS good_fid, + IS_NON_ZERO(small_cls, medium_cls, large_cls) AS any_cls, + IS_GOOD(small_cls, medium_cls, large_cls) AS good_cls, + IS_NON_ZERO(fast_lcp, avg_lcp, slow_lcp) AS any_lcp, + IS_GOOD(fast_lcp, avg_lcp, slow_lcp) AS good_lcp, + IF('${pastMonth}' < '2024-01-01', + (IS_GOOD(fast_fid, avg_fid, slow_fid) OR fast_fid IS NULL) AND + IS_GOOD(small_cls, medium_cls, large_cls) AND + IS_GOOD(fast_lcp, avg_lcp, slow_lcp), + (IS_GOOD(fast_inp, avg_inp, slow_inp) OR fast_inp IS NULL) AND + IS_GOOD(small_cls, medium_cls, large_cls) AND + IS_GOOD(fast_lcp, avg_lcp, slow_lcp) + ) AS good_cwv, + + # WV + IS_NON_ZERO(fast_fcp, avg_fcp, slow_fcp) AS any_fcp, + IS_GOOD(fast_fcp, avg_fcp, slow_fcp) AS good_fcp, + IS_NON_ZERO(fast_ttfb, avg_ttfb, slow_ttfb) AS any_ttfb, + IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb) AS good_ttfb, + IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp, + IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp + FROM geo_summary + ), UNNEST(eligible_ranks) AS rank ), From cc6e7273acfdeba46febdeb5183ef0574f350bf7 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 04:11:42 +0200 Subject: [PATCH 07/12] renamed --- definitions/output/reports/tech_crux.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 8822a121..e5e3da98 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -128,7 +128,7 @@ WITH pages AS ( ${constants.devRankFilter} ), -geo_summary AS ( +crux_base AS ( SELECT \`chrome-ux-report\`.experimental.GET_COUNTRY(country_code) AS geo, rank, @@ -246,7 +246,7 @@ crux AS ( IS_GOOD(fast_ttfb, avg_ttfb, slow_ttfb) AS good_ttfb, IS_NON_ZERO(fast_inp, avg_inp, slow_inp) AS any_inp, IS_GOOD(fast_inp, avg_inp, slow_inp) AS good_inp - FROM geo_summary + FROM crux_base ), UNNEST(eligible_ranks) AS rank ), From 41499509d04b0c2244d9b75d8b03fe668e7c3549 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 13:47:34 +0200 Subject: [PATCH 08/12] no mapping --- definitions/output/reports/tech_crux.js | 94 ++++++++++--------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index e7f75cb7..c7dd1f29 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -42,61 +42,44 @@ const results = [] for (const category of Object.keys(lighthouse?.categories ? lighthouse.categories : {})) { for (const audit of lighthouse.categories[category].auditRefs) { - // Moving lighthouse to insights https://developer.chrome.com/blog/moving-lighthouse-to-insights - if (category === 'performance' && '${pastMonth}' < '2025-10-01') { - if ( - [ - 'first-meaningful-paint', - 'no-document-write', - 'offscreen-images', - 'uses-passive-event-listeners', - 'uses-rel-preload', - 'third-party-facades' - ].includes(audit.id) - ) { - continue; // Deprecated audits - } else if ( - lighthouse.audits[audit.id].score === 1 // Only include audits that passed - && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits - ) { - // Map old audit IDs to new insight audit IDs - const performanceAuditIdMapping = { - 'layout-shifts': 'cls-culprits-insight', - 'non-composited-animations': 'cls-culprits-insight', - 'unsized-images': 'cls-culprits-insight', - 'redirects': 'document-latency-insight', - 'server-response-time': 'document-latency-insight', - 'uses-text-compression': 'document-latency-insight', - 'dom-size': 'dom-size-insight', - 'duplicated-javascript': 'duplicated-javascript-insight', - 'font-display': 'font-display-insight', - 'modern-image-formats': 'image-delivery-insight', - 'uses-optimized-images': 'image-delivery-insight', - 'efficient-animated-content': 'image-delivery-insight', - 'uses-responsive-images': 'image-delivery-insight', - 'work-during-interaction': 'interaction-to-next-paint-insight', - 'prioritize-lcp-image': 'lcp-discovery-insight', - 'lcp-lazy-loaded': 'lcp-discovery-insight', - 'largest-contentful-paint-element': 'lcp-phases-insight', - 'legacy-javascript': 'legacy-javascript-insight', - 'uses-http2': 'modern-http-insight', - 'critical-request-chains': 'network-dependency-tree-insight', - 'uses-rel-preconnect': 'network-dependency-tree-insight', - 'render-blocking-resources': 'render-blocking-insight', - 'third-party-summary': 'third-parties-insight', - 'uses-long-cache-ttl': 'use-cache-insight', - 'viewport': 'viewport-insight' - }; - - // Use mapped audit ID if available, otherwise use original - const mappedAuditId = performanceAuditIdMapping[audit.id] || audit.id; - - // Push the audit with the category and mapped ID - results.push({ - category, - id: mappedAuditId - }); - } + // Deprecated audits: + // Moving lighthouse to insights https://developer.chrome.com/blog/moving-lighthouse-to-insights + if ( + [ + 'first-meaningful-paint', + 'no-document-write', + 'offscreen-images', + 'uses-passive-event-listeners', + 'uses-rel-preload', + 'third-party-facades', + "layout-shifts" + "non-composited-animations", + "unsized-images", + "redirects", + "server-response-time", + "uses-text-compression", + "dom-size", + "duplicated-javascript", + "font-display", + "modern-image-formats", + "uses-optimized-images", + "efficient-animated-content", + "uses-responsive-images", + "work-during-interaction", + "prioritize-lcp-image", + "lcp-lazy-loaded", + "largest-contentful-paint-element", + "legacy-javascript", + "uses-http2", + "critical-request-chains", + "uses-rel-preconnect", + "render-blocking-resources", + "third-party-summary", + "uses-long-cache-ttl", + "viewport" + ].includes(audit.id) + ) { + continue; } if ( @@ -406,6 +389,7 @@ audits_summary AS ( ARRAY_AGG(STRUCT( category AS category, id AS id, + audits.origins AS origins, SAFE_DIVIDE(audits.origins, base_summary.origins) AS pass_rate )) AS audits FROM audits From 43b1a9773aab27498edcd9356174d9d254abd9ac Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 13:52:59 +0200 Subject: [PATCH 09/12] keep absolute origins --- definitions/output/reports/tech_crux.js | 77 +++++++++---------- .../output/reports/tech_report_audits.js | 16 ++-- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index c7dd1f29..4c86f1f2 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -294,40 +294,6 @@ lab_data AS ( version ), -audits AS ( - SELECT - geo, - client, - rank, - technology, - version, - category, - id, - COUNT(DISTINCT root_page) AS origins - FROM ( - SELECT DISTINCT - client, - page, - root_page, - audits.category, - audits.id - FROM pages - INNER JOIN UNNEST(get_passed_audits(pages.lighthouse)) AS audits - ) AS audits_data - INNER JOIN technologies - USING (client, page) - INNER JOIN crux - USING (client, root_page) - GROUP BY - geo, - client, - rank, - technology, - version, - category, - id -), - base_summary AS ( SELECT geo, @@ -387,14 +353,43 @@ audits_summary AS ( technology, version, ARRAY_AGG(STRUCT( - category AS category, - id AS id, - audits.origins AS origins, - SAFE_DIVIDE(audits.origins, base_summary.origins) AS pass_rate + category, + id, + pass_origins )) AS audits - FROM audits - LEFT JOIN base_summary - USING (geo, client, rank, technology, version) + FROM ( + SELECT + geo, + client, + rank, + technology, + version, + category, + id, + COUNT(DISTINCT root_page) AS pass_origins + FROM ( + SELECT DISTINCT + client, + page, + root_page, + audits.category, + audits.id + FROM pages + INNER JOIN UNNEST(get_passed_audits(pages.lighthouse)) AS audits + ) AS audits_data + INNER JOIN technologies + USING (client, page) + INNER JOIN crux + USING (client, root_page) + GROUP BY + geo, + client, + rank, + technology, + version, + category, + id + ) GROUP BY geo, client, diff --git a/definitions/output/reports/tech_report_audits.js b/definitions/output/reports/tech_report_audits.js index eaf57052..184d9079 100644 --- a/definitions/output/reports/tech_report_audits.js +++ b/definitions/output/reports/tech_report_audits.js @@ -16,7 +16,7 @@ CREATE TEMP FUNCTION GET_AUDITS( audits ARRAY> >> ) @@ -24,10 +24,10 @@ RETURNS ARRAY, desktop STRUCT< - pass_rate FLOAT64 + pass_origins FLOAT64 > >> LANGUAGE js AS ''' @@ -45,15 +45,15 @@ records.forEach(function(record) { auditMap[key] = { category: audit.category, id: audit.id, - mobile: { pass_rate: 0 }, - desktop: { pass_rate: 0 } + mobile: { pass_origins: 0 }, + desktop: { pass_origins: 0 } }; } - // Add the pass_rate to the proper client type. + // Add the pass_origins to the proper client type. if (record.client === 'mobile') { - auditMap[key].mobile.pass_rate += audit.pass_rate; + auditMap[key].mobile.pass_origins += audit.pass_origins; } else if (record.client === 'desktop') { - auditMap[key].desktop.pass_rate += audit.pass_rate; + auditMap[key].desktop.pass_origins += audit.pass_origins; } }); }); From 63b367e1cf099ee7a6c10019ed497b4f0e6d557c Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:59:57 +0200 Subject: [PATCH 10/12] fix --- definitions/output/reports/tech_crux.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 4c86f1f2..46160543 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -52,7 +52,7 @@ for (const category of Object.keys(lighthouse?.categories ? lighthouse.categorie 'uses-passive-event-listeners', 'uses-rel-preload', 'third-party-facades', - "layout-shifts" + "layout-shifts", "non-composited-animations", "unsized-images", "redirects", From 40d6245bb204c52a806b0597a14cec866ec9e3a8 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 15:14:10 +0200 Subject: [PATCH 11/12] keep all audits --- definitions/output/reports/tech_crux.js | 41 ------------------------- 1 file changed, 41 deletions(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 46160543..2da0a44a 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -41,47 +41,6 @@ const results = [] for (const category of Object.keys(lighthouse?.categories ? lighthouse.categories : {})) { for (const audit of lighthouse.categories[category].auditRefs) { - - // Deprecated audits: - // Moving lighthouse to insights https://developer.chrome.com/blog/moving-lighthouse-to-insights - if ( - [ - 'first-meaningful-paint', - 'no-document-write', - 'offscreen-images', - 'uses-passive-event-listeners', - 'uses-rel-preload', - 'third-party-facades', - "layout-shifts", - "non-composited-animations", - "unsized-images", - "redirects", - "server-response-time", - "uses-text-compression", - "dom-size", - "duplicated-javascript", - "font-display", - "modern-image-formats", - "uses-optimized-images", - "efficient-animated-content", - "uses-responsive-images", - "work-during-interaction", - "prioritize-lcp-image", - "lcp-lazy-loaded", - "largest-contentful-paint-element", - "legacy-javascript", - "uses-http2", - "critical-request-chains", - "uses-rel-preconnect", - "render-blocking-resources", - "third-party-summary", - "uses-long-cache-ttl", - "viewport" - ].includes(audit.id) - ) { - continue; - } - if ( lighthouse.audits[audit.id].score === 1 // Only include audits that passed && !['metrics', 'hidden'].includes(audit.group) // Exclude metrics and hidden audits From 9c0d8637e31ddd8a934688a291cf904adffb1d43 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Mon, 9 Jun 2025 15:19:07 +0200 Subject: [PATCH 12/12] support data with no rank --- definitions/output/reports/tech_crux.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/definitions/output/reports/tech_crux.js b/definitions/output/reports/tech_crux.js index 2da0a44a..1f190abe 100644 --- a/definitions/output/reports/tech_crux.js +++ b/definitions/output/reports/tech_crux.js @@ -162,7 +162,7 @@ crux AS ( WHEN rank <= 100000 THEN ['Top 100k', 'Top 1M', 'Top 10M', 'ALL'] WHEN rank <= 1000000 THEN ['Top 1M', 'Top 10M', 'ALL'] WHEN rank <= 10000000 THEN ['Top 10M', 'ALL'] - WHEN rank <= 100000000 THEN ['ALL'] + ELSE ['ALL'] END AS eligible_ranks, CONCAT(origin, '/') AS root_page, IF(device = 'desktop', 'desktop', 'mobile') AS client,