Çoğu web uygulaması görsel yüklemelerini hâlâ bir kara kutu gibi yönetiyor. Bir kullanıcı bir dosya bırakır, tarayıcı onu gönderir ve sunucu ya veri yükünü kabul eder ya da kimsenin hazırlıklı olmadığı bir 413 hatası fırlatır. Tarayıcı tarafında sıkıştırma denklemi değiştirir. Veri yüklerini ağa ulaşmadan önce küçültme şansı verir; bu da daha hızlı yüklemeler, daha düşük bant genişliği faturaları ve daha az sunucu zaman aşımı anlamına gelir. Ancak bu işi yanlış yapmak kolaydır. Sıkıştırmayı "kalite" etiketli sihirli bir sürgü gibi ele alırsanız; bozuk resimler, uzamış küçük resimler ve kafa karıştırıcı kullanıcı deneyimleri sunarsınız. Daha iyi olan yaklaşım, tüm akışı bir işlem hattı (pipeline) olarak ele almaktır.
Sürgülerle Değil, İşlem Hatlarıyla Düşünün
İşi ayrık aşamalara bölün. Dosyayı input elementinden okuyun. Görüntüyü hedef boyutlarınıza göre ölçeklendirin. Yeni bir Blob kodlayın. Ardından sonucu kullanıcıya geri render edin. Her aşama tek bir iş yapar ve çıktısını bir sonrakine aktarır. Bu ayrım sadece kodun daha düzenli olmasını sağlamaz; aynı zamanda birim testini (unit testing) de kolaylaştırır. Bir dosya girişine hiç dokunmadan, ölçeklendirme aşamasına bilinen bir buffer besleyebilirsiniz. Sunucuyla olan gidiş-dönüş sürecini beklemeden, kodlayıcınızın 200 KB altı bir JPEG üretip üretmediğini doğrulayabilirsiniz. Bir şeyler bozulduğunda, tam olarak hangi adımın başarısız olduğunu bilirsiniz.
Bu görevleri ayrı tutmak, yüklemeler sırasında sürprizleri de önler. Ölçeklendirme ve kodlamayı tek bir karmaşık fonksiyonda toplarsanız, işlemin ortasındaki bir kod çözme hatası yükleme kuyruğunuzu tutarsız bir durumda bırakabilir. Bir işlem hattı, her sınırda doğrulama yapmanızı zorunlu kılar. Dosya kod çözülemiyorsa, henüz bir canvas oluşturmadan bunu yakalarsınız. Kodlanmış Blob çok büyükse, sunucudan bunu depolamasını istemeden önce durumu fark edersiniz.
Kod Yazmadan Önce Bir Sözleşme Belirleyin
Herhangi biri bir canvas çizim çağrısı (draw call) yapmadan önce, kuralları yazın ve ekiple paylaşın. Kabul edilen MIME türlerini seçin. JPEG, PNG, WebP veya AVIF'e izin verecek misiniz? Her birinin alfa kanalları, tarayıcı desteği ve CPU maliyeti üzerinde farklı etkileri vardır. Maksimum bir giriş boyutu belirleyin. Amiral gemisi bir telefondan gelen 30 MB'lık ham bir fotoğrafı tamamen bellekte kod çözmeye çalışırsanız, eski bir dizüstü bilgisayarı dondurabilir veya çökertebilirsiniz. Maksimum çıktı boyutlarını tanımlayın. Eğer kullanıcı arayüzünüz (UI) hiçbir zaman 2048 pikselden geniş resimler göstermiyorsa, 6000 piksel genişliğindeki bir fotoğrafın işlem hattından geçmesine izin vermenizin bir anlamı yoktur.
En önemlisi, kod çözme hataları için plan yapın. Bozuk bir dosya, egzotik bir renk profili veya yarıda kesilmiş bir yükleme, Image constructor üzerinde hata fırlatabilir. İşlem hattınızın net bir catch bloğuna ve insan tarafından okunabilir bir hata mesajına ihtiyacı vardır. Tarayıcının sessizce ölmesine ve hiçbir şey olmazken kullanıcının bir spinner'a bakakalmasına izin vermeyin.
Görüntüye Saygı Duyun
Bozulmalar amatörce görünür. En-boy oranını koruyun ve en uzun kenarı sınırlayın. Hedef kutunuz 1024 x 1024 piksel ise, 4000 x 3000 piksellik bir fotoğraf 1024 x 1024 değil, 1024 x 768 boyutuna gelmelidir. Ölçekleme faktörünü uzun kenardan hesaplayın ve kısa kenarın onu takip etmesini sağlayın. Bu, görüntülerin tuhaf şekillere doğru uzamasını engeller.
Gerçek dışa aktarma işlemi için canvas toBlob metodunu kullanın. Bu metod size çıktı formatı ve kalite ayarı üzerinde doğrudan kontrol sağlar ve ana iş parçacığını (main thread) engellememek için asenkron çalışır. Bir offscreen canvas oluşturun, yeniden boyutlandırılmış görüntüyü üzerine çizin ve ardından tercih ettiğiniz tip ve kalite değeriyle canvas.toBlob çağrısını yapın. Yükleme mantığınıza veya depolama API'nize ileteceğiniz şey işte bu yeni Blob'dur.
Kanıtları Gösterin
Sıkıştırma görünmez bir iştir. Eğer rakamları görünür kılmazsanız, kullanıcılar sürece güvenmeyecektir. Kullanıcıların orijinali sonuçla karşılaştırmasına olanak tanıyan bir arayüz oluşturun. Orijinal dosya boyutunu, yeni dosya boyutunu, yeni boyutları ve nihai format türünü görüntüleyin. 4.2 MB'lık bir telefon fotoğrafının 380 KB'lık bir WebP'ye düştüğünü görmek, görüntüyü gizlice bozduğunuz korkusunu ortadan kaldırır.
Bu şeffaflık sorun gidermeye de yardımcı olur. Bir kullanıcı yüklemenin başarısız olduğundan şikayet ettiğinde, kontrol edeceğiniz ilk şey çıktı boyutlarının sunucu limitinizi aşıp aşmadığı veya formatın PNG'den JPEG'e dönüşüp alfa kanalını düşürüp düşürmediği olacaktır. Kullanıcının bir destek talebi açmadan önce sorunu kendi başına teşhis edebilmesi için bu verileri UI'ya yerleştirin.
Ön Ayarlar Yeniden Sıkıştırmadan Daha İyidir
Aynı görüntüyü asla iki kez sıkıştırmayın. Kayıplı (lossy) bir kodlayıcıdan her geçiş, daha fazla detayı siler ve bloklu artefaktlar oluşturur. Eğer bir kullanıcının üst üste "optimize et" butonuna basmasına izin verirseniz, üçüncü nesil bir fotokopinin fotokopisi gibi görünecektir. Bunun yerine, her çıktıyı orijinal kaynak dosyadan oluşturun ve şu ön ayarları sunun:
- Smaller file: Push quality lower and cap dimensions aggressively for thumbnails or fast previews.
- Balanced: Target a moderate quality level with sensible dimensions, suitable for social feeds and galleries.
- More detail: Keep quality high and preserve larger dimensions for photography, artwork, or print previews.
Store the original Blob in memory so the user can switch between presets without stacking generations of loss. Always generate from the source, never from the last output.
Test Like Your Users Upload
Your development machine with a fiber connection and 32 GB of RAM is not reality. Test with the actual files real users carry. Phone photos from iOS and Android use different metadata orientations and may originate from HEIC sources. Transparent assets such as logos and icons behave differently under JPEG conversion because JPEG simply does not support alpha channels. Huge files will expose memory limits on devices with 2 GB of RAM. Slow mobile CPUs will reveal exactly how long that toBlob call really takes.
Use Chrome DevTools to throttle the CPU and network. Try a five-year-old Android phone. If your pipeline locks the UI for three seconds while encoding, you need to move the heavy work into a Web Worker so the interface stays responsive.
Ship the Basics First
It is tempting to support every format and
