Skip to content

Commit

Permalink
Move functionality from co2 to sitespeed.io. (#4034)
Browse files Browse the repository at this point in the history
* Move functionality from co2 to sitespeed.io.

See thegreenwebfoundation/co2.js#182

* lint
  • Loading branch information
soulgalore committed Dec 21, 2023
1 parent db87c99 commit 5211c51
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 15 deletions.
104 changes: 104 additions & 0 deletions lib/plugins/sustainable/helper.js
Original file line number Diff line number Diff line change
@@ -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 };
}
23 changes: 16 additions & 7 deletions lib/plugins/sustainable/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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 = {
Expand All @@ -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
Expand Down
14 changes: 7 additions & 7 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 5211c51

Please sign in to comment.