Merhaba arkadaşlar, bugün sizlere web sitelerindeki en büyük performans düşmanlarından biri olan resim optimizasyonu için yazdığım, beni çok rahatlatan bir otomasyon script'inden bahsedeceğim. Özellikle e-ticaret veya galeri siteleri yapıyorsanız, yüzlerce resmi tek tek optimize etmek gerçekten kafayı yedirtiyor. Ben de "Bu işin bir yolu olmalı" deyip kolları sıvadım.
Neden AVIF ve Neden Otomasyon?
WebP'nin bile yanına yaklaşamadığı sıkıştırma oranlarından bahsediyoruz. AVIF formatı, aynı kalitedeki bir JPEG veya WebP'den ortalama %50 daha küçük dosya boyutları sunabiliyor. Tabii ki destekleyen tarayıcılar için (Chrome, Firefox, Opera gibi). Peki, her yeni resim eklediğinizde bunu manuel yapmak mı? Hayır, olmaz. Benim çözümüm: Bir klasöre attığınız tüm resimleri (JPEG, PNG, vs.) otomatik olarak AVIF'e çeviren, aynı zamanda bir yedek olarak WebP de üreten ve `<picture>` elementine uygun HTML kodunu hazırlayan bir Node.js script'i.
Kurulum ve Gereksinimler
Öncelikle sisteminizde Node.js ve ImageMagick kurulu olmalı. ImageMagick, AVIF dönüşümünün arka planındaki sihirbaz. Projenize `sharp` kütüphanesini de yüklüyoruz, çünkü WebP dönüşümü için onu kullanacağız.
Chokidar kütüphanesi, belirlediğimiz klasördeki dosya değişikliklerini (yeni resim eklenmesini) izlememizi sağlayacak.
Script'in Çalışma Mantığı ve Kodları
Script'imizin yapacağı işlem sırası şöyle:
1. Belirlediğimiz `./images/original` klasörünü izle.
2. Buraya yeni bir resim (jpg, png, jpeg) atıldığında yakala.
3. `sharp` ile WebP versiyonunu oluştur ve `./images/webp` klasörüne kaydet.
4. ImageMagick komutu ile AVIF versiyonunu oluştur ve `./images/avif` klasörüne kaydet.
5. Konsola, bu resim için kullanılabilecek `<picture>` HTML kodunu yazdır.
İşte benim `image-watcher.js` dosyamın temel hali:
Kullanım ve Sonuçlar
Script'i çalıştırmak için terminalde `node image-watcher.js` yazmanız yeterli. Artık `./images/original/` klasörüne sürükleyip bıraktığınız her resim için, `webp` ve `avif` klasörlerinde optimize edilmiş halleri otomatik oluşacak. En güzeli de, tarayıcı destek durumuna göre en iyi formatı sunan HTML kodunu hazır olarak alacaksınız.
Bu script ile bir projemdeki ürün galerisi resimlerinin ortalama boyutunu %65 civarında düşürmeyi başardım. Lighthouse performans skoru da epey yükseldi tabii.
Peki ya siz? Resim optimizasyonu için hangi yöntemleri kullanıyorsunuz? Next.js Image component veya başka bir framework'ün built-in çözümleriyle mi çalışıyorsunuz? Yoksa sizin de benim gibi kendi küçük otomasyon araçlarınız var mı? Yorumlarda deneyimlerinizi paylaşın, tartışalım!
WebP'nin bile yanına yaklaşamadığı sıkıştırma oranlarından bahsediyoruz. AVIF formatı, aynı kalitedeki bir JPEG veya WebP'den ortalama %50 daha küçük dosya boyutları sunabiliyor. Tabii ki destekleyen tarayıcılar için (Chrome, Firefox, Opera gibi). Peki, her yeni resim eklediğinizde bunu manuel yapmak mı? Hayır, olmaz. Benim çözümüm: Bir klasöre attığınız tüm resimleri (JPEG, PNG, vs.) otomatik olarak AVIF'e çeviren, aynı zamanda bir yedek olarak WebP de üreten ve `<picture>` elementine uygun HTML kodunu hazırlayan bir Node.js script'i.
Öncelikle sisteminizde Node.js ve ImageMagick kurulu olmalı. ImageMagick, AVIF dönüşümünün arka planındaki sihirbaz. Projenize `sharp` kütüphanesini de yüklüyoruz, çünkü WebP dönüşümü için onu kullanacağız.
JavaScript:
npm init -y
npm install sharp
npm install --save-dev chokidar
Chokidar kütüphanesi, belirlediğimiz klasördeki dosya değişikliklerini (yeni resim eklenmesini) izlememizi sağlayacak.
Script'imizin yapacağı işlem sırası şöyle:
1. Belirlediğimiz `./images/original` klasörünü izle.
2. Buraya yeni bir resim (jpg, png, jpeg) atıldığında yakala.
3. `sharp` ile WebP versiyonunu oluştur ve `./images/webp` klasörüne kaydet.
4. ImageMagick komutu ile AVIF versiyonunu oluştur ve `./images/avif` klasörüne kaydet.
5. Konsola, bu resim için kullanılabilecek `<picture>` HTML kodunu yazdır.
İşte benim `image-watcher.js` dosyamın temel hali:
JavaScript:
const chokidar = require('chokidar');
const sharp = require('sharp');
const { exec } = require('child_process');
const path = require('path');
const fs = require('fs');
// İzlenecek klasör
const watchPath = './images/original/';
const webpOutputPath = './images/webp/';
const avifOutputPath = './images/avif/';
// Çıktı klasörlerini kontrol et, yoksa oluştur
[fs.existsSync(webpOutputPath) || fs.mkdirSync(webpOutputPath, { recursive: true });
fs.existsSync(avifOutputPath) || fs.mkdirSync(avifOutputPath, { recursive: true });]
const watcher = chokidar.watch(watchPath, {
ignored: /(^|[\/\\])\../, // gizli dosyaları yoksay
persistent: true,
awaitWriteFinish: true // Dosya yazma işlemi bitene kadar bekle
});
watcher
.on('add', async (filePath) => {
const fileName = path.basename(filePath, path.extname(filePath));
const webpFileName = `${fileName}.webp`;
const avifFileName = `${fileName}.avif`;
console.log(`Yeni resim tespit edildi: ${fileName}`);
// 1. WebP Dönüşümü (sharp ile)
try {
await sharp(filePath)
.webp({ quality: 80 }) // Kaliteyi ihtiyaca göre ayarla
.toFile(path.join(webpOutputPath, webpFileName));
console.log(`✅ WebP oluşturuldu: ${webpFileName}`);
} catch (err) {
console.error('WebP oluşturma hatası:', err);
}
// 2. AVIF Dönüşümü (ImageMagick ile)
const avifCommand = `magick convert "${filePath}" -quality 70 "${path.join(avifOutputPath, avifFileName)}"`;
exec(avifCommand, (error) => {
if (error) {
console.error('AVIF oluşturma hatası:', error);
return;
}
console.log(`✅ AVIF oluşturuldu: ${avifFileName}`);
// 3. HTML Çıktısını Göster
console.log('\n--- Kullanabileceğiniz HTML Kodu ---');
console.log(`
<picture>
<source srcset="/images/avif/${avifFileName}" type="image/avif">
<source srcset="/images/webp/${webpFileName}" type="image/webp">
<img src="${filePath}" alt="Açıklama" loading="lazy">
</picture>
`);
console.log('------------------------------------\n');
});
})
.on('error', error => console.error(`İzleyici hatası: ${error}`));
console.log(`🟢 Resim izleyici başlatıldı: ${watchPath} klasörü dinleniyor...`);
Script'i çalıştırmak için terminalde `node image-watcher.js` yazmanız yeterli. Artık `./images/original/` klasörüne sürükleyip bıraktığınız her resim için, `webp` ve `avif` klasörlerinde optimize edilmiş halleri otomatik oluşacak. En güzeli de, tarayıcı destek durumuna göre en iyi formatı sunan HTML kodunu hazır olarak alacaksınız.
Bu script ile bir projemdeki ürün galerisi resimlerinin ortalama boyutunu %65 civarında düşürmeyi başardım. Lighthouse performans skoru da epey yükseldi tabii.
Peki ya siz? Resim optimizasyonu için hangi yöntemleri kullanıyorsunuz? Next.js Image component veya başka bir framework'ün built-in çözümleriyle mi çalışıyorsunuz? Yoksa sizin de benim gibi kendi küçük otomasyon araçlarınız var mı? Yorumlarda deneyimlerinizi paylaşın, tartışalım!