Skip to content

Commit 1284e9f

Browse files
authored
Merge pull request #141 from mgifford/copilot/fix-google-analytics-page-loads
Fix third-party JS size total to use page-load-weighted bytes
2 parents 9804eaa + 0b8282b commit 1284e9f

3 files changed

Lines changed: 90 additions & 4 deletions

File tree

src/publish/render-pages.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,7 @@ function renderTechSummarySection(report) {
19571957
third_party_service_counts = {},
19581958
third_party_service_urls = {},
19591959
third_party_service_total_bytes = {},
1960+
third_party_service_page_load_totals = {},
19601961
accessibility_statement_summary = null,
19611962
required_links_summary = null
19621963
} = summary;
@@ -2008,7 +2009,9 @@ function renderTechSummarySection(report) {
20082009
const totalBytes = third_party_service_total_bytes[name] ?? 0;
20092010
if (totalBytes > 0 && count > 0) {
20102011
const perPageBytes = Math.round(totalBytes / count);
2011-
sizeCell = `${formatBytes(perPageBytes)} <span class="tp-size-total">(${formatBytes(totalBytes)} total)</span>`;
2012+
const pageLoadTotal = third_party_service_page_load_totals[name] ?? 0;
2013+
const weightedTotal = pageLoadTotal > 0 ? perPageBytes * pageLoadTotal : totalBytes;
2014+
sizeCell = `${formatBytes(perPageBytes)} <span class="tp-size-total">(${formatBytes(weightedTotal)} total)</span>`;
20122015
} else {
20132016
sizeCell = '<span class="tp-size-unknown">&#8212;</span>';
20142017
}

src/scanners/tech-detector.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -434,15 +434,16 @@ export function detectTechnologies(lighthouseRaw) {
434434
* USWDS. Returns counts and a deduplicated list of observed USWDS versions.
435435
* Also aggregates third-party service usage and transfer sizes across all scanned URLs.
436436
*
437-
* @param {Array<{ scan_status: string, detected_technologies?: object }>} urlResults
437+
* @param {Array<{ scan_status: string, detected_technologies?: object, page_load_count?: number }>} urlResults
438438
* @returns {{
439439
* cms_counts: Record<string, number>,
440440
* uswds_count: number,
441441
* uswds_versions: string[],
442442
* total_scanned: number,
443443
* third_party_service_counts: Record<string, number>,
444444
* third_party_service_urls: Record<string, string[]>,
445-
* third_party_service_total_bytes: Record<string, number>
445+
* third_party_service_total_bytes: Record<string, number>,
446+
* third_party_service_page_load_totals: Record<string, number>
446447
* }}
447448
*/
448449
export function buildTechSummary(urlResults = []) {
@@ -455,6 +456,7 @@ export function buildTechSummary(urlResults = []) {
455456
const thirdPartyServiceCounts = {};
456457
const thirdPartyServiceUrls = {};
457458
const thirdPartyServiceTotalBytes = {};
459+
const thirdPartyServicePageLoadTotals = {};
458460

459461
for (const result of successful) {
460462
const tech = result.detected_technologies;
@@ -463,6 +465,7 @@ export function buildTechSummary(urlResults = []) {
463465
}
464466

465467
const url = result.url ?? null;
468+
const pageLoadCount = result.page_load_count ?? 0;
466469

467470
if (tech.cms) {
468471
cmsCounts[tech.cms] = (cmsCounts[tech.cms] ?? 0) + 1;
@@ -490,6 +493,8 @@ export function buildTechSummary(urlResults = []) {
490493
if (!thirdPartyServiceUrls[serviceName]) thirdPartyServiceUrls[serviceName] = [];
491494
thirdPartyServiceUrls[serviceName].push(url);
492495
}
496+
thirdPartyServicePageLoadTotals[serviceName] =
497+
(thirdPartyServicePageLoadTotals[serviceName] ?? 0) + pageLoadCount;
493498
}
494499

495500
const sizes = tech.third_party_service_sizes ?? {};
@@ -510,6 +515,7 @@ export function buildTechSummary(urlResults = []) {
510515
total_scanned: successful.length,
511516
third_party_service_counts: thirdPartyServiceCounts,
512517
third_party_service_urls: thirdPartyServiceUrls,
513-
third_party_service_total_bytes: thirdPartyServiceTotalBytes
518+
third_party_service_total_bytes: thirdPartyServiceTotalBytes,
519+
third_party_service_page_load_totals: thirdPartyServicePageLoadTotals
514520
};
515521
}

tests/unit/tech-detector.test.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,3 +590,80 @@ test('buildTechSummary handles results with no third_party_service_sizes field',
590590
assert.equal(summary.third_party_service_counts['Google Analytics'], 1);
591591
assert.deepEqual(summary.third_party_service_total_bytes, {});
592592
});
593+
594+
// ---------------------------------------------------------------------------
595+
// third_party_service_page_load_totals – buildTechSummary
596+
// ---------------------------------------------------------------------------
597+
598+
test('buildTechSummary returns empty third_party_service_page_load_totals for empty results', () => {
599+
const summary = buildTechSummary([]);
600+
assert.deepEqual(summary.third_party_service_page_load_totals, {});
601+
});
602+
603+
test('buildTechSummary accumulates page_load_count per service across successful results', () => {
604+
const results = [
605+
{
606+
url: 'https://site1.gov/',
607+
page_load_count: 5000000,
608+
scan_status: 'success',
609+
detected_technologies: {
610+
cms: null,
611+
uswds: { detected: false, version: null },
612+
third_party_services: ['Google Analytics', 'Google Fonts'],
613+
third_party_service_sizes: { 'Google Analytics': 30720, 'Google Fonts': 5120 }
614+
}
615+
},
616+
{
617+
url: 'https://site2.gov/',
618+
page_load_count: 2000000,
619+
scan_status: 'success',
620+
detected_technologies: {
621+
cms: null,
622+
uswds: { detected: false, version: null },
623+
third_party_services: ['Google Analytics'],
624+
third_party_service_sizes: { 'Google Analytics': 20480 }
625+
}
626+
},
627+
{
628+
url: 'https://site3.gov/',
629+
page_load_count: 999999,
630+
scan_status: 'failed',
631+
detected_technologies: {
632+
cms: null,
633+
uswds: { detected: false, version: null },
634+
third_party_services: ['Google Analytics'],
635+
third_party_service_sizes: { 'Google Analytics': 99999 }
636+
}
637+
}
638+
];
639+
const summary = buildTechSummary(results);
640+
assert.equal(summary.third_party_service_page_load_totals['Google Analytics'], 7000000);
641+
assert.equal(summary.third_party_service_page_load_totals['Google Fonts'], 5000000);
642+
assert.equal(summary.third_party_service_page_load_totals['YouTube'], undefined);
643+
});
644+
645+
test('buildTechSummary treats missing page_load_count as 0 in page load totals', () => {
646+
const results = [
647+
{
648+
url: 'https://site1.gov/',
649+
scan_status: 'success',
650+
detected_technologies: {
651+
cms: null,
652+
uswds: { detected: false, version: null },
653+
third_party_services: ['Google Analytics']
654+
}
655+
},
656+
{
657+
url: 'https://site2.gov/',
658+
page_load_count: 3000000,
659+
scan_status: 'success',
660+
detected_technologies: {
661+
cms: null,
662+
uswds: { detected: false, version: null },
663+
third_party_services: ['Google Analytics']
664+
}
665+
}
666+
];
667+
const summary = buildTechSummary(results);
668+
assert.equal(summary.third_party_service_page_load_totals['Google Analytics'], 3000000);
669+
});

0 commit comments

Comments
 (0)