thegreenwebfoundation / co2.js

An npm module for accessing the green web API, and estimating the carbon emissions from using digital services
https://developers.thegreenwebfoundation.org/
Other
414 stars 54 forks source link

WIP v0.10.x - Create perVisit method for SWD model #95

Closed fershad closed 2 years ago

fershad commented 2 years ago

This update addresses #94, making the more recent Sustainable Web Design model the default for emissions calculations, adding the perVisit model.

How will results differ between early versions and v0.11.0 with the SWD model?

Since the SWD model include more of the system in calculations for the same levels of data transfer, the resulting emissions calculations will be slightly higher than 1byte model.

Option to switch to models

This PR also introduces the ability for a model options parameter (as a string) to be passed to the CO2 constructor when it is initiated. In doing so, those who still wish to use the 1byte model for their calculations can continue to do so by making a small updated to their code.

To-do:

mrchrisadams commented 2 years ago

Thanks for this Fershad.

As we discussed on the call, this brings up a decision to make - about how we support multiple models.

I had initially thought about this in terms of passing in a separate model as a entire object like the SustainableWebDesign class in sustainable-web-design.js.

Models like the SWD one would essentially agree to a contract by implementing a series of methods we would expect to call, as would any future model, or version of a model. This PR makes me wonder about that now.

If we use the string approach as you have proposed

I like that by just passing in a string, to tell CO2js which method to use, we reduce code we might need outside of importing CO2.js.

The consequence is that in the CO2 js object, we need to have more knowledge of all the possible models at work.

If we use the approach of passing an model object in

If we chose to keep accepting a model class, it means that the CO2.js object stays simpler, but we'd likely need an simple way to fetch the SWD model, and we'd be able to support more models, and more versions of a given models

However, we end needing a bit more setup when using the CO2.js object.

We only have two models - this might be a premature optimisation.

No action needed yet - just sharing my thoughts now for working on later this week.


mrchrisadams commented 2 years ago

Hey @fershad - I've published the 0.10.x release of co2.js.

It's visible by default now, so this PR should now work against it.

After having a think, I think your approach of passing the string in instead of an actual javascript object is neater.

Does this give you enough to proceed?

mrchrisadams commented 2 years ago

Yeah, using the string code would be waaay nicer.

It would mean we could easily make the different models usable from inside an observable notebook like this.

By passing in different 'model' strings, you could see the difference between the different models. This would be really helpful for explaining how the different models work, and what assumptions they make.

https://observablehq.com/@mrchrisadams/can-i-now-use-co2-js-in-observable-code

fershad commented 2 years ago

@mrchrisadams I've merged the v.0.10.1 release into this branch. Just want to confirm changes that I'll work on for v0.11.0

  1. ⭐️ Switch default model to SWD
  2. Provide a way for developers to use the 1byte model
  3. Create a perView method for SWD & expose it via CO2.js
  4. Create some safeguards to prevent the library failing if empty or incomplete model parameters are set.
mrchrisadams commented 2 years ago

Hi @fershad - agreed.

The only thing worth looking discussing in more might be this one, as I our documentation should reflect the guidance on perView versus perByte.

Create a perView method for SWD & expose it via CO2.js

I understand the caching assumptions to be provided in the absense of better data, but when extending existing web perf tooling to use CO2.js, it will often make its own assumptions about caching, that we need to account for.

If you do not want to use the caching assumptions in the SWD model

Call energyPerByteByComponent, to get the energy figures, then call co2byComponent to convert these energy figures to carbon - this is what perbyte does, to maintain compatibility with existing users of CO2.js, which make their own assumptions about caching based on their own data.

energyPerByteByComponent basically gives you the energy figures for a given number of bytes, split based on the different components in the model. You would use this if you want to make no assumptions about caching.

co2byComponent then takes these figures, and applies a carbon intensity figure to give CO2 numbers

If you do want to use the caching assumptions in the SWD model

I think this is the where your perVisit bit comes in. We have two functions here

Call energyPerVisitByComponent to get the energy figures with default caching assumptions in SWD applied.

Then call co2byComponent convert these to carbon figures, broken down by component.

I'm assuming the perVisit method you described would carry out these steps, so it's comparable to the perByte figure before, right?

If so, this this would be ideal.

Making the order of the functions easier to understand

Do you think it's worth rearranging the order of the functions in the file too, so functions doing similar things are grouped together?

// the main 'API' we expose, calculating carbon
perByte
perVisit

// working with just energy, with or without caching
energyPerByteByComponent
energyVisitByComponent

// just the energy figure, as a single number, no breakdown
energyPerByte
energyPerVisit

// return the co2 figures for the components, used by perbyte and perVisit
co2byComponent

// the earlier functions used for creating annual, or monthly figures,  from co2 or energy numbers
// these are here to maintain compatibility with EcoPing
annualEnergyInKwh
annualSegmentEnergy
annualEmissionsInGrams
emissionsPerVisitInGrams

Of the last ones, I think it's worth asking about the validity of emissionsPerVisitInGrams as there the carbon intensity multiplier is being applied across every component.

This would only make sense if the country where we modelled the usage in was the same country as where equipment was manufactured, and if we knew for sure that the device usage took place in that same country too. It might be applicable in China, but less so elsewhere.

https://github.com/thegreenwebfoundation/co2.js/blob/main/src/sustainable-web-design.js#L199

fershad commented 2 years ago

Notes from our conversation around this PR.

This will now be patch version bump (0.10.x), with v.0.11.0 being planned for later in August. The scope for this PR will be reduced to:

  1. Create a perVisit method for SWD & expose it via CO2.js
  2. Create some safeguards to prevent the library failing if empty or incomplete model parameters are set.
  3. Add documentation on how to publish to NPM

It's important to note that the 1byte model will remain the default in v0.10.x

We will change the default model to sustainable web design in v0.11.0