perf: optimize blog assets for low bandwidth
This commit is contained in:
+20
-10
@@ -26,7 +26,7 @@ function formatBytes(bytes) {
|
||||
async function optimizeImage(inputPath, outputPath, options = {}) {
|
||||
const { width, quality = 80, outputExt = '.webp' } = options;
|
||||
const originalSize = await getFileSize(inputPath);
|
||||
|
||||
|
||||
let pipeline = sharp(inputPath);
|
||||
|
||||
if (width) {
|
||||
@@ -40,19 +40,20 @@ async function optimizeImage(inputPath, outputPath, options = {}) {
|
||||
}
|
||||
|
||||
const buffer = await pipeline.toBuffer();
|
||||
|
||||
// For standard images, if webp is larger, we'll keep it if it's the specific target like bgImage
|
||||
// but for general article images we might skip.
|
||||
const optimizedSize = buffer.length;
|
||||
|
||||
// Threshold: webp must be at least 10% smaller than original
|
||||
const isTargeted = inputPath.includes(SOURCE_DIR);
|
||||
if (!isTargeted && buffer.length >= originalSize && outputExt === '.webp') {
|
||||
console.log(`Skipping ${path.basename(inputPath)}: Optimized size (${formatBytes(buffer.length)}) >= original (${formatBytes(originalSize)})`);
|
||||
const reductionRatio = (originalSize - optimizedSize) / originalSize;
|
||||
|
||||
if (!isTargeted && reductionRatio < 0.1 && outputExt === '.webp') {
|
||||
console.log(`Skipping ${path.basename(inputPath)}: Reduction ${ (reductionRatio * 100).toFixed(2) }% < 10% threshold`);
|
||||
return null;
|
||||
}
|
||||
|
||||
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
||||
await fs.writeFile(outputPath, buffer);
|
||||
const optimizedSize = buffer.length;
|
||||
|
||||
|
||||
return {
|
||||
inputPath,
|
||||
outputPath,
|
||||
@@ -60,7 +61,7 @@ async function optimizeImage(inputPath, outputPath, options = {}) {
|
||||
outputName: path.basename(outputPath),
|
||||
originalSize,
|
||||
optimizedSize,
|
||||
reduction: ((originalSize - optimizedSize) / originalSize * 100).toFixed(2) + '%'
|
||||
reduction: (reductionRatio * 100).toFixed(2) + '%'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,7 +90,16 @@ async function main() {
|
||||
if (res) results.push(res);
|
||||
}
|
||||
|
||||
// 4. Optimize Article Images (In-place WebP generation)
|
||||
// 4. Optimize Cover Images in Public Assets
|
||||
const coverImages = await glob('src/.vuepress/public/assets/images/cover*.{jpg,jpeg,png}');
|
||||
console.log(`Found ${coverImages.length} cover images to process...`);
|
||||
for (const img of coverImages) {
|
||||
const outputWebp = img.replace(path.extname(img), '.webp');
|
||||
const res = await optimizeImage(img, outputWebp, { quality: 80 });
|
||||
if (res) results.push(res);
|
||||
}
|
||||
|
||||
// 5. Optimize Article Images (In-place WebP generation)
|
||||
const articleImages = await glob('src/**/*.{jpg,jpeg,png}', {
|
||||
ignore: ['src/.vuepress/dist/**', 'src/.vuepress/public/**']
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user