nprapps / dailygraphics-templates

Graphic templates for the dailygraphics-next rig
11 stars 14 forks source link

Rewrite imports/requires for easier treeshaking #24

Open thomaswilburn opened 2 years ago

thomaswilburn commented 2 years ago

When using the Rollup bundler (and possibly with the older Browserify bundler, but I haven't tested that), treeshaking will dramatically reduce the size of D3--but only if the imports are discoverable through explicit imports, exports. For example, the current setup:

var d3 = {
  ...require("d3-scale")
}

...will effectively load all of d3-scale, totalling I think about 100KB of code. Whereas if only the functions that are actually used get imported...

var { scaleLinear } = require("d3-scale");

var d3 = { scaleLinear };

Then the bundler can cull everything that isn't directly relevant to linear scales, meaning that the bundle size can drop quite a bit.

Whether this delivers benefits when you're actually loading all the things that a typical graphic might use, I'm not sure, but initial tests on a renderStackedGroupedColumn() graphic (which has is probably on the upper side of template imports) indicates that it went from 219KB when deployed to 147KB, which is not nothing. The header ends up looking something like this:

var { select } = require("d3-selection");
var { scaleBand, scaleLinear, scaleOrdinal } = require("d3-scale");
var { axisBottom, axisLeft } = require("d3-axis");

var d3 = {
  select,
  scaleBand, scaleLinear, scaleOrdinal,
  axisBottom, axisLeft
};

If we didn't bother re-wrapping the d3 object and just used the imported functions, it also improves the initial import ergonomics a little (no double-declarations needed) at the cost of making it less obvious when you're using the library in the actual code.

Ironically, it performs better when using the un-minified versions than the /dist/d3-whatever.min version, which might also help make error traces a bit more readable.