Created
February 5, 2025 15:52
-
-
Save demostanis/18fdaeb0b7ee8a53281cdf416be92f69 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import puppeteer from "puppeteer"; | |
import imagemin from "imagemin"; | |
import imageminWebp from "imagemin-webp"; | |
import Fontmin from "fontmin"; | |
import pino from "pino"; | |
if (process.argv.length < 3) { | |
console.error("usage: node main.js url"); | |
process.exit(1); | |
} | |
const logger = pino(); | |
const readBody = (type, response, page) => { | |
return new Promise(async resolve => { | |
const url = response.url(); | |
const mime = response.headers()["content-type"]; | |
logger.debug({ url, mime }, "found " + type); | |
try { | |
resolve(await response.buffer()); | |
} catch (err) { | |
logger.warn({ url, mime, err }, "failed to fetch " + type); | |
resolve(null); | |
} | |
}); | |
} | |
const imageHandler = async (type, response, page) => { | |
const raw = await readBody(type, response, page); | |
if (!raw) return; | |
const compressed = await imagemin.buffer(raw, { | |
plugins: [ | |
imageminWebp() | |
] | |
}); | |
if (raw.length > compressed.length) { | |
const savedBytes = raw.length-compressed.length | |
logger.info({ url: response.url(), savedBytes }, "compressed image"); | |
// TODO: stream to the backend | |
} | |
} | |
const fontHandler = async (type, response, page) => { | |
const raw = await readBody(type, response, page); | |
if (!raw) return; | |
const fontmin = new Fontmin() | |
.use(new Fontmin.ttf2woff2()) | |
.src(raw); | |
const results = await fontmin.runAsync(); | |
if (results.length > 1) { | |
const compressed = results.reduce((a, b) => | |
a._contents.length < b._contents.length ? | |
a._contents : b._contents) | |
if (raw.length > compressed.length) { | |
const savedBytes = raw.length-compressed.length | |
logger.info({ url: response.url(), savedBytes }, "compressed font"); | |
// TODO: stream to the backend | |
} | |
} | |
} | |
const resourceHandlers = {"image": imageHandler, "font": fontHandler}; | |
logger.info("opening browser..."); | |
const browser = await puppeteer.launch(); | |
const page = await browser.newPage(); | |
while (process.argv.length != 2) { | |
const url = process.argv[2]; | |
page.on("response", response => { | |
const type = response.request().resourceType(); | |
resourceHandlers[type]?.(type, response, page); | |
}); | |
logger.info({ url }, "navigating"); | |
try { | |
await page.goto(url); | |
} catch { | |
logger.error({ url }, "invalid url"); | |
} | |
process.argv.splice(2, 1); | |
} | |
//await browser.close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment