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);