mediahub-fe/scripts/optimize-images.js

119 lines
3.3 KiB
JavaScript

const sharp = require('sharp');
const fs = require('fs');
const path = require('path');
const optimizeImage = async (inputPath, outputPath, options = {}) => {
const {
quality = 80,
width,
height,
format = 'webp'
} = options;
try {
let pipeline = sharp(inputPath);
if (width || height) {
pipeline = pipeline.resize(width, height, {
fit: 'inside',
withoutEnlargement: true
});
}
switch (format) {
case 'webp':
pipeline = pipeline.webp({ quality });
break;
case 'avif':
pipeline = pipeline.avif({ quality });
break;
case 'jpeg':
pipeline = pipeline.jpeg({ quality });
break;
case 'png':
pipeline = pipeline.png({ quality });
break;
}
await pipeline.toFile(outputPath);
const inputStats = fs.statSync(inputPath);
const outputStats = fs.statSync(outputPath);
const savings = ((inputStats.size - outputStats.size) / inputStats.size * 100).toFixed(2);
console.log(`✅ Optimized: ${path.basename(inputPath)}`);
console.log(` Original: ${(inputStats.size / 1024 / 1024).toFixed(2)}MB`);
console.log(` Optimized: ${(outputStats.size / 1024 / 1024).toFixed(2)}MB`);
console.log(` Savings: ${savings}%`);
console.log('');
} catch (error) {
console.error(`❌ Failed to optimize ${inputPath}:`, error.message);
}
};
const optimizeDirectory = async (dirPath) => {
const files = fs.readdirSync(dirPath);
for (const file of files) {
const filePath = path.join(dirPath, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
await optimizeDirectory(filePath);
} else if (stat.isFile()) {
const ext = path.extname(file).toLowerCase();
if (['.jpg', '.jpeg', '.png', '.gif'].includes(ext)) {
const fileSize = stat.size / 1024 / 1024; // MB
// Only optimize files larger than 100KB
if (fileSize > 0.1) {
const outputPath = filePath.replace(ext, '.webp');
// Determine optimal dimensions based on file size
let targetWidth, targetHeight;
if (fileSize > 5) { // Very large files
targetWidth = 1920;
targetHeight = 1080;
} else if (fileSize > 1) { // Large files
targetWidth = 1200;
targetHeight = 800;
} else if (fileSize > 0.5) { // Medium files
targetWidth = 800;
targetHeight = 600;
}
await optimizeImage(filePath, outputPath, {
quality: 80,
width: targetWidth,
height: targetHeight,
format: 'webp'
});
}
}
}
}
};
// Optimize specific problematic directories
const optimizeProject = async () => {
console.log('🚀 Starting image optimization...\n');
const directories = [
'public/assets',
'public/images/all-img',
'public/images/users',
'public/images/avatar'
];
for (const dir of directories) {
if (fs.existsSync(dir)) {
console.log(`📁 Processing directory: ${dir}`);
await optimizeDirectory(dir);
}
}
console.log('✅ Image optimization complete!');
};
// Run the optimization
optimizeProject().catch(console.error);