Skip to content

Commit 3657aa3

Browse files
🏗️🚀:minify the script the site serves
The counter shipped as it is written upstream, comments and all. It is squeezed on the way out instead: 9,213 bytes to 5,774, and 3,327 to 2,263 once gzipped, which is the figure that counts. The copy in the repository is untouched, which is what lets both things be true at once: a reader downloads the small one, and the one here stays byte for byte what upstream serves, so `nps verify.vendored` can still tell whether it has fallen behind. A minifier drops comments, and the two lines this one opens with are its terms rather than decoration -- ISC asks for the notice in every copy. They are kept, along with anything marked `@license` or `@preserve`. Images and scripts are both copied rather than rendered, so neither meets a transform; the pass over the output now knows what to do with each. That leaves nothing served here that is not squeezed: markup, styles, marks and now this. Signed-off-by: Derek Lewis <DerekNonGeneric@inf.is> Assisted-by: Claude-Code:claude-opus-5 PR-URL: #1867 Fixes: #1548
1 parent 3817ce2 commit 3657aa3

3 files changed

Lines changed: 40 additions & 8 deletions

File tree

eleventy.config.mjs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { execFileSync } from 'node:child_process';
22
import { readdir, readFile, writeFile } from 'node:fs/promises';
3-
import { join, parse as pathParse } from 'node:path';
3+
import { extname, join, parse as pathParse } from 'node:path';
44
import { EleventyI18nPlugin } from '@11ty/eleventy';
55
import { PATHS } from '@openinf/portal/build/constants';
66
import { hasViewBox, replaceInlineSvg } from '@openinf/portal/build/inline-svg';
@@ -13,6 +13,7 @@ import markdownItGitHubAlerts from 'markdown-it-github-alerts';
1313
import postcss from 'postcss';
1414
import { compileString } from 'sass';
1515
import { optimize as optimizeSvg } from 'svgo';
16+
import { minify as minifyJs } from 'terser';
1617

1718
// skipcq: JS-0116
1819
export default async function (eleventyConfig) {
@@ -221,21 +222,48 @@ export default async function (eleventyConfig) {
221222
return replaceInlineSvg(content, (svg) => shrinkSvg(svg, inline));
222223
});
223224

224-
// Images are copied rather than rendered, so no transform reaches them.
225+
// What a script says about its own license has to reach whoever receives
226+
// it. The vendored counter is ISC, which asks for the notice in every
227+
// copy, and a minifier drops comments unless told which ones are not
228+
// decoration.
229+
const License = /@license|@preserve|ISC license|GoatCounter:/;
230+
231+
/**
232+
* Minifies a script, keeping whatever states its terms.
233+
* @param {string} code The script.
234+
* @returns {Promise<string>} The minified script.
235+
*/
236+
const shrinkJs = async (code) => {
237+
const { code: minified } = await minifyJs(code, {
238+
format: { comments: (_node, comment) => License.test(comment.value) },
239+
});
240+
241+
return minified ?? code;
242+
};
243+
244+
/** What is squeezed on the way out, and how. */
245+
const squeezers = {
246+
'.svg': shrinkSvg,
247+
'.js': shrinkJs,
248+
};
249+
250+
// Assets are copied rather than rendered, so no transform reaches them.
225251
eleventyConfig.on('eleventy.after', async ({ dir }) => {
226252
const entries = await readdir(dir.output, {
227253
recursive: true,
228254
withFileTypes: true,
229255
});
230256

231257
await Promise.all(
232-
entries
233-
.filter((entry) => entry.isFile() && entry.name.endsWith('.svg'))
234-
.map(async (entry) => {
235-
const file = join(entry.parentPath, entry.name);
258+
entries.map(async (entry) => {
259+
const squeeze = squeezers[extname(entry.name)];
260+
261+
if (!entry.isFile() || squeeze === undefined) return;
262+
263+
const file = join(entry.parentPath, entry.name);
236264

237-
await writeFile(file, shrinkSvg(await readFile(file, 'utf8')));
238-
})
265+
await writeFile(file, await squeeze(await readFile(file, 'utf8')));
266+
})
239267
);
240268
});
241269

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"stylelint-config-recess-order": "7.8.0",
9292
"stylelint-config-standard-scss": "17.0.0",
9393
"svgo": "4.0.2",
94+
"terser": "5.50.0",
9495
"typescript": "7.0.2",
9596
"unified": "11.0.5",
9697
"vnu-jar": "26.8.15",

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)