Perf: Remove optimizeCss (causes render-blocking CSS), compress 94 photos via sharp/mozjpeg (avg ~70% size reduction)
@@ -15,7 +15,6 @@ const nextConfig = {
|
||||
pagesBufferLength: 2,
|
||||
},
|
||||
experimental: {
|
||||
optimizeCss: true,
|
||||
staleTimes: {
|
||||
dynamic: 0,
|
||||
static: 30,
|
||||
|
||||
|
Before Width: | Height: | Size: 1007 KiB After Width: | Height: | Size: 360 KiB |
|
Before Width: | Height: | Size: 777 KiB After Width: | Height: | Size: 297 KiB |
|
Before Width: | Height: | Size: 522 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 488 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 574 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 447 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 570 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 304 KiB After Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 304 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 342 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 540 KiB After Width: | Height: | Size: 198 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 618 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 422 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 702 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 380 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 664 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 546 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 636 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 877 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 894 KiB After Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 402 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 755 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 306 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 686 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 606 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 432 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 314 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 597 KiB After Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 493 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 371 KiB After Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 629 KiB After Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 659 KiB After Width: | Height: | Size: 263 KiB |
|
Before Width: | Height: | Size: 664 KiB After Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 648 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 710 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 844 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 655 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 771 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 919 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 577 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 675 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 689 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 614 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 895 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 315 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 346 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 664 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 633 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 543 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 468 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 492 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 384 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 317 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 328 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 442 KiB After Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 355 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 336 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 346 KiB After Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 276 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 305 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 376 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 326 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 408 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 339 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 623 KiB After Width: | Height: | Size: 227 KiB |
|
Before Width: | Height: | Size: 774 KiB After Width: | Height: | Size: 288 KiB |
|
Before Width: | Height: | Size: 601 KiB After Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 238 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 233 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 87 KiB |
46
scripts/compress-photos.mjs
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Aggressively compresses all photos in public/assets/photos/ to max 1280px
|
||||
* and quality 70 using sharp. Target: all files under 200KB.
|
||||
*/
|
||||
import sharp from 'sharp';
|
||||
import { readdir, stat } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
|
||||
const PHOTOS_DIR = 'public/assets/photos';
|
||||
const MAX_WIDTH = 1280;
|
||||
const QUALITY = 70;
|
||||
const MAX_BYTES = 200_000;
|
||||
|
||||
const files = await readdir(PHOTOS_DIR);
|
||||
const imageFiles = files.filter(f => /\.(jpg|jpeg|JPG|JPEG)$/i.test(f));
|
||||
|
||||
let compressed = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const file of imageFiles) {
|
||||
const fullPath = join(PHOTOS_DIR, file);
|
||||
const { size } = await stat(fullPath);
|
||||
|
||||
if (size <= MAX_BYTES) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`Compressing: ${file} (${Math.round(size / 1024)}KB)`);
|
||||
try {
|
||||
const buf = await sharp(fullPath)
|
||||
.rotate() // auto-orient from EXIF
|
||||
.resize({ width: MAX_WIDTH, withoutEnlargement: true })
|
||||
.jpeg({ quality: QUALITY, progressive: true, mozjpeg: true })
|
||||
.toBuffer();
|
||||
|
||||
await sharp(buf).toFile(fullPath);
|
||||
const afterSize = (await stat(fullPath)).size;
|
||||
console.log(` → ${Math.round(afterSize / 1024)}KB (saved ${Math.round((size - afterSize) / 1024)}KB)`);
|
||||
compressed++;
|
||||
} catch (err) {
|
||||
console.error(` ✗ Failed: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nDone: ${compressed} compressed, ${skipped} already small.`);
|
||||