perf: nén panorama 4096px + xuất WebP, LQIP theo path webp

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
tuyenio
2026-06-25 09:01:13 +07:00
parent c96b6f195c
commit 5e9e632345
55 changed files with 48 additions and 32 deletions
+20 -5
View File
@@ -10,7 +10,8 @@ const MODAL_DIR = path.join(ROOT, "public/modal");
const BACKUP_DIR = path.join(ROOT, "image-originals");
const LQIP_OUT = path.join(ROOT, "src/app/tours/chua-thai-lac.lqip.ts");
const PANO_WIDTH = 6144;
const PANO_WIDTH = 4096;
const PANO_WEBP_QUALITY = 78;
const PANO_QUALITY = 80;
const LQIP_WIDTH = 32;
const MODAL_FILES = ["modal-1.png", "modal-2.png"];
@@ -38,17 +39,31 @@ async function optimizePanoramas() {
const src = await sourceFrom(dest, "chua-thai-lac");
const before = (await fs.stat(dest)).size;
const buf = await sharp(src)
// JPEG (giữ cho next/image ở trang landing) — cũng hạ về 4096
const jpgBuf = await sharp(src)
.rotate()
.resize({ width: PANO_WIDTH, withoutEnlargement: true })
.jpeg({ quality: PANO_QUALITY, mozjpeg: true, progressive: true })
.toBuffer();
await fs.writeFile(dest, buf);
await fs.writeFile(dest, jpgBuf);
// WebP (tour viewer nạp bản này) — cùng tên, đuôi .webp
const webpName = f.replace(/\.jpe?g$/i, ".webp");
const webpDest = path.join(PANO_DIR, webpName);
const webpBuf = await sharp(src)
.rotate()
.resize({ width: PANO_WIDTH, withoutEnlargement: true })
.webp({ quality: PANO_WEBP_QUALITY })
.toBuffer();
await fs.writeFile(webpDest, webpBuf);
// LQIP khóa theo path .webp (đúng path tour yêu cầu)
const lqipBuf = await sharp(src).rotate().resize({ width: LQIP_WIDTH }).jpeg({ quality: 40 }).toBuffer();
lqip["/images/chua-thai-lac/" + f] = "data:image/jpeg;base64," + lqipBuf.toString("base64");
lqip["/images/chua-thai-lac/" + webpName] = "data:image/jpeg;base64," + lqipBuf.toString("base64");
console.log(`${f}: ${fmt(before)} -> ${fmt(buf.length)} (-${Math.round((1 - buf.length / before) * 100)}%)`);
console.log(
`${f}: ${fmt(before)} -> jpg ${fmt(jpgBuf.length)} | webp ${fmt(webpBuf.length)}`,
);
}
return lqip;
}