Move functionality from co2 to sitespeed.io. (#4034)

* Move functionality from co2 to sitespeed.io.

See https://github.com/thegreenwebfoundation/co2.js/issues/182

* lint
This commit is contained in:
Peter Hedenskog 2023-12-21 05:47:06 +01:00 committed by GitHub
parent db87c99839
commit 5211c51d0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 15 deletions

View File

@ -0,0 +1,104 @@
// Moved from the co2.js project
// see https://github.com/thegreenwebfoundation/co2.js/issues/182
export function perDomain(pageXray, greenDomains, CO2) {
const co2PerDomain = [];
for (let domain of Object.keys(pageXray.domains)) {
let co2;
co2 =
greenDomains && greenDomains.includes(domain)
? CO2.perByte(pageXray.domains[domain].transferSize, true)
: CO2.perByte(pageXray.domains[domain].transferSize);
co2PerDomain.push({
domain,
co2,
transferSize: pageXray.domains[domain].transferSize
});
}
co2PerDomain.sort((a, b) => b.co2 - a.co2);
return co2PerDomain;
}
export function perPage(pageXray, green, CO2) {
// Accept an xray object, and if we receive a boolean as the second
// argument, we assume every request we make is sent to a server
// running on renwewable power.
// if we receive an array of domains, return a number accounting the
// reduced CO2 from green hosted domains
const domainCO2 = perDomain(pageXray, green, CO2);
let totalCO2 = 0;
for (let domain of domainCO2) {
totalCO2 += domain.co2;
}
return totalCO2;
}
export function perContentType(pageXray, greenDomains, CO2) {
const co2PerContentType = {};
for (let asset of pageXray.assets) {
const domain = new URL(asset.url).domain;
const transferSize = asset.transferSize;
const co2ForTransfer = CO2.perByte(
transferSize,
greenDomains && greenDomains.includes(domain)
);
const contentType = asset.type;
if (!co2PerContentType[contentType]) {
co2PerContentType[contentType] = { co2: 0, transferSize: 0 };
}
co2PerContentType[contentType].co2 += co2ForTransfer;
co2PerContentType[contentType].transferSize += transferSize;
}
// restructure and sort
const all = [];
for (let type of Object.keys(co2PerContentType)) {
all.push({
type,
co2: co2PerContentType[type].co2,
transferSize: co2PerContentType[type].transferSize
});
}
all.sort((a, b) => b.co2 - a.co2);
return all;
}
export function getDirtiestResources(pageXray, greenDomains, CO2) {
const allAssets = [];
for (let asset of pageXray.assets) {
const domain = new URL(asset.url).domain;
const transferSize = asset.transferSize;
const co2ForTransfer = CO2.perByte(
transferSize,
greenDomains && greenDomains.includes(domain)
);
allAssets.push({ url: asset.url, co2: co2ForTransfer, transferSize });
}
allAssets.sort((a, b) => b.co2 - a.co2);
return allAssets.slice(0, allAssets.length > 10 ? 10 : allAssets.length);
}
export function perParty(pageXray, greenDomains, CO2) {
let firstParty = 0;
let thirdParty = 0;
// calculate co2 per first/third party
const firstPartyRegEx = pageXray.firstPartyRegEx;
for (let d of Object.keys(pageXray.domains)) {
// eslint-disable-next-line unicorn/prefer-regexp-test
if (d.match(firstPartyRegEx)) {
thirdParty += CO2.perByte(
pageXray.domains[d].transferSize,
greenDomains && greenDomains.includes(d)
);
} else {
firstParty += CO2.perByte(
pageXray.domains[d].transferSize,
greenDomains && greenDomains.includes(d)
);
}
}
return { firstParty, thirdParty };
}

View File

@ -8,6 +8,13 @@ import intel from 'intel';
import { co2, hosting } from '@tgwf/co2';
import { SitespeedioPlugin } from '@sitespeed.io/plugin';
import { Aggregator } from './aggregator.js';
import {
getDirtiestResources,
perParty,
perContentType,
perPage,
perDomain
} from './helper.js';
const fsp = fs.promises;
const __dirname = fileURLToPath(new URL('.', import.meta.url));
@ -129,7 +136,7 @@ export default class SustainablePlugin extends SitespeedioPlugin {
}
const CO2 = new co2(this.sustainableOptions.model);
const co2PerDomain = CO2.perDomain(message.data, hostingGreenCheck);
const co2PerDomain = perDomain(message.data, hostingGreenCheck, CO2);
const baseDomain = message.data.baseDomain;
const hostingInfo = {
@ -142,21 +149,23 @@ export default class SustainablePlugin extends SitespeedioPlugin {
hostingInfo.green = true;
}
const co2PerParty = CO2.perParty(message.data, hostingGreenCheck);
const co2PerParty = perParty(message.data, hostingGreenCheck, CO2);
// Fetch the resources with the largest CO2 impact. ie,
// the resources to optimise, host somewhere green, or contact
// a supplier about
const dirtiestResources = CO2.dirtiestResources(
const dirtiestResources = getDirtiestResources(
message.data,
hostingGreenCheck
hostingGreenCheck,
CO2
);
const co2PerContentType = CO2.perContentType(
const co2PerContentType = perContentType(
message.data,
hostingGreenCheck
hostingGreenCheck,
CO2
);
const co2PerPageView = CO2.perPage(message.data, hostingGreenCheck);
const co2PerPageView = perPage(message.data, hostingGreenCheck, CO2);
const totalCO2 = this.sustainableOptions.pageViews
? this.sustainableOptions.pageViews * co2PerPageView

14
npm-shrinkwrap.json generated
View File

@ -12,7 +12,7 @@
"@google-cloud/storage": "6.9.5",
"@influxdata/influxdb-client": "1.33.2",
"@sitespeed.io/plugin": "0.0.6",
"@tgwf/co2": "0.13.6",
"@tgwf/co2": "0.13.10",
"aws-sdk": "2.1327.0",
"axe-core": "4.8.2",
"browsertime": "19.3.1",
@ -1026,9 +1026,9 @@
}
},
"node_modules/@tgwf/co2": {
"version": "0.13.6",
"resolved": "https://registry.npmjs.org/@tgwf/co2/-/co2-0.13.6.tgz",
"integrity": "sha512-uV8y2voiAb9iQwzK+5dTFLNBu5P5/oCyMAvqD3/+X74sMCc/N2+4MhIY9JmpO1gBQykE647dd4l/40GiE7cKSw==",
"version": "0.13.10",
"resolved": "https://registry.npmjs.org/@tgwf/co2/-/co2-0.13.10.tgz",
"integrity": "sha512-iQZMYdLP+l1Kyi03EEE4jAZgzlAA8HRAbfgT3GgN6sUgbSoNS/UHijICUqgkum9aHIkDSOrtwkgbB/x3Gc/cQA==",
"engines": {
"node": ">=14.0.0"
}
@ -10048,9 +10048,9 @@
}
},
"@tgwf/co2": {
"version": "0.13.6",
"resolved": "https://registry.npmjs.org/@tgwf/co2/-/co2-0.13.6.tgz",
"integrity": "sha512-uV8y2voiAb9iQwzK+5dTFLNBu5P5/oCyMAvqD3/+X74sMCc/N2+4MhIY9JmpO1gBQykE647dd4l/40GiE7cKSw=="
"version": "0.13.10",
"resolved": "https://registry.npmjs.org/@tgwf/co2/-/co2-0.13.10.tgz",
"integrity": "sha512-iQZMYdLP+l1Kyi03EEE4jAZgzlAA8HRAbfgT3GgN6sUgbSoNS/UHijICUqgkum9aHIkDSOrtwkgbB/x3Gc/cQA=="
},
"@tokenizer/token": {
"version": "0.3.0",

View File

@ -80,7 +80,7 @@
"dependencies": {
"@google-cloud/storage": "6.9.5",
"@influxdata/influxdb-client": "1.33.2",
"@tgwf/co2": "0.13.6",
"@tgwf/co2": "0.13.10",
"aws-sdk": "2.1327.0",
"axe-core": "4.8.2",
"browsertime": "19.3.1",