Ana içeriğe geç

Base64 Resim Boyutu: %33 Artış Neden Olur?

Base64 Resim Boyutu: %33 Artış Neden Olur? - Teknik SEO Rehberi

Base64 ile encode edilmiş bir PNG dosyasını HTML veya CSS içine gömdüğünüzde, tarayıcı o veriyi doğru okur; ama dosyanın boyutu orijinalinden büyüktür. Bu büyüme rastgele değil: her encode işleminde %33 civarında gerçekleşir. Neden tam bu oran, neden değişmez ve bu rakamın performans üzerindeki gerçek etkisi ne zaman kritik hale gelir?

Base64 encoding nedir: 3 byte, 4 karakter

Base64, ikili veriyi (binary data) yalnızca ASCII karakterlerden oluşan bir diziye dönüştüren bir kodlama şemasıdır. Temel motivasyon, binary veriyi e-posta gövdesi veya HTML niteliği gibi metin tabanlı taşıma kanallarında güvenle iletebilmektir. Görüntü dosyaları, PDF'ler ve fontlar bu kodlama sayesinde <img src="data:image/png;base64,..."> biçiminde doğrudan belgelere gömülebilir.

Algoritmanın çalışma mantığı şöyledir: giriş verisi 3'er byte'lık gruplara bölünür. Her 3 byte, 24 bit eder. Bu 24 bit, 6'şar bitlik 4 parçaya ayrılır. Her 6 bitlik parça, 64 karakterden oluşan bir alfabede (A-Z, a-z, 0-9, + ve /) karşılığı olan tek bir karaktere dönüştürülür. Her 3 byte girdi, 4 byte çıktı üretir.

Giriş uzunluğu 3'ün katı değilse sona = veya == karakteri eklenir; bu padding hem çıktının 4'ün katı uzunlukta kalmasını sağlar hem de decoder'ın orijinal veri sınırını tanımasına olanak tanır.

%33 büyüme: neden bu rakam sabittir?

Rakam yuvarlak değil. Sabit.

3 byte → 4 karakter dönüşümü, boyutu her zaman 4/3 katsayısıyla artırır; bu oran yaklaşık 1.3333... olduğundan encode sonrası dosya orijinalinden tam olarak %33.33 büyür; padding karakterleri bu oranı birkaç byte mertebesinde etkileyebilir ama yüzde olarak ihmal edilebilir düzeyde kalır.

Bir örnek üzerinden ilerleyelim: 90 KB boyutundaki bir PNG dosyasını base64 ile encode ettiğinizde elde edeceğiniz string yaklaşık 120 KB'tır. 300 KB'lık bir JPEG için bu değer 400 KB'ye çıkar. Oranın kaynağı değişmediği için sonuç deterministiktir; farklı araçlar veya farklı işletim sistemleri arasında fark oluşmaz.

Sıkıştırma bu denklemi nasıl etkiler? GZIP veya Brotli ile sıkıştırıldığında base64 string'leri binary forma kıyasla daha kötü sıkışır. Bunun nedeni, base64 alfabesinin yalnızca 64 farklı karakter içermesine rağmen entropy düzeninin GZIP'in pattern-matching algoritmalarına az elverişli bir biçimde dağılmasıdır. Binary veri %60-70 sıkışırken aynı içeriğin base64 gösterimi genellikle %20-30 oranında sıkışır; net fark her zaman binary lehine açılır.

GZIP net farkı kapatmıyor.

Diğer bir deyişle: transfer boyutu hesabı yapılırken "base64 ile gönderiyorum ama GZIP de var, ofset olur" çıkarımı yanlıştır. GZIP her iki formata da uygulandığında binary her zaman öndedir.

Resim boyutunu daha da artıran ek etkenler

%33 salt encode kaynaklı artışa eklenen diğer maliyetler var. Bunların bir kısmı doğrudan, bir kısmı dolaylı etkilidir.

İlk etken CSS veya HTML içine gömme biçimidir. Bir data URI <style> bloğuna yazıldığında, tarayıcı o CSS dosyasını ayrıştırırken karşılaştığı base64 string'ini decode ederek piksel verisine dönüştürür; bu işlem render bloğu içinde gerçekleşir. Harici bir <img> dosyasında ayrıştırma render tamamlandıktan sonra asenkron başlar. Şişmiş bir kritik CSS dosyası, first contentful paint süresini doğrudan geciktirebilir.

Çıkan sonuç sezgiselin tam tersi.

İkinci etken HTTP başlık maliyetidir. Harici bir görsel tek bir HTTP isteğiyle taşınır ve CDN'de önbelleğe alınır; base64 gömer misiniz, her sayfa yüklemesinde HTML veya CSS yanıtının bir parçası olarak taşınır. HTTP/1.1 ortamında bu ayrım belirsizleşebilir, ancak HTTP/2 çoğullaması (multiplexing) devredeyken aynı bağlantı üzerinden paralel istekler zararsız hale geldiğinden harici dosya avantajı öne çıkar. Ek HTTP isteğini ortadan kaldırmak, HTTP/2'nin aktif olduğu bir altyapıda neredeyse sıfır performans kazancına karşılık gelir.

Üçüncü etken JavaScript tarafındaki çözümleme maliyetidir. Canvas API veya WebGL gibi bağlamlarda base64 ile alınan resim verisi önce atob() ile çözülmeli, ardından Uint8Array'e dönüştürülmelidir; bu iki adım main-thread üzerinde çalışır ve büyük resimler için ölçülebilir bir gecikme üretir. base64 verisini hızlıca çözümlemek ve boyutunu kontrol etmek için geliştirme sürecinde anlık geri bildirim almanız bu maliyeti önceden görmenizi sağlar.

HTTP isteğini ortadan kaldırmak tek başına yeterli gerekçe değil

Base64 ile resimleri HTML veya CSS içine gömmek, popülerliğini HTTP/1.1 döneminden alan bir optimizasyon tekniğidir. O dönemde tarayıcılar her domain için yalnızca 6 eşzamanlı bağlantı kurabiliyordu; sprite ve data URI teknikleri bu kısıtı aşmak için anlamlıydı. HTTP/2 bu kısıtı yapısal olarak ortadan kaldırdı.

Cache kaybı en somut maliyettir.

Harici bir görsel dosyası bir kez indirilir, tarayıcı önbelleğinde saatler veya günlerce yaşar. Aynı resmi base64 olarak HTML içine gömdüğünüzde, HTML dosyası güncellendiğinde tüm resimler yeniden indirilir; CSS içine gömdüğünüzde, CSS cache'i kırıldığında resimler de kırılır. Statik varlıklar için uzun TTL değerleri belirleyip bunları versiyon hash'iyle yönetmek, yaygın bir CDN stratejisidir; base64 bu stratejiyi doğrudan engeller.

Kritik CSS şişmesi ayrı bir risk oluşturur. Above-the-fold içerik için satır içi CSS uygulandığında, bir veya iki base64 resim bu kritik yükü birkaç katına çıkarabilir. 14 KB altında tutulması önerilen kritik CSS kütlesini 60-70 KB'ye taşıyan projeler, render-blocking süresini iyileştirmek yerine artırmış olur. Bu durumda CSS dosyasını boyut açısından küçültmek yalnızca kısmi bir çözüm üretir; asıl sorun CSS içine gömülü base64 varlığın orada bulunmaması gerektiğidir.

Buna karşılık değiştirme maliyeti de ihmal edilmemelidir. Base64 string HTML veya CSS dosyasına gömüldüğünde, resmi güncellemek için tüm dosyayı yeniden deploy etmek gerekir; harici görsel dosyasında yalnızca görsel değiştirilir, HTML dokunulmadan kalır. Büyük ölçekli projelerde bu fark bakım sürtünmesine dönüşür.

Data URI ne zaman kabul edilebilir: karar değişkenleri

Tüm bu maliyet kalemleri base64'ü her zaman yanlış tercih yapmaz; bağlam değişkene göre karar verir.

Boyut eşiği pratik bir başlangıç noktasıdır. 1-2 KB altındaki SVG ikonları veya küçük bitmap göstergeleri için data URI kabul edilebilir; %33 artış 1 KB'de 333 byte eder ve cache avantajını anlamsız kılar. 5 KB üzerindeki görsel varlıklarda harici dosya tutarlı biçimde öndedir.

Tekrar kullanım sayısı kritik değişkendir. Tek bir sayfada bir kez görünen, hiçbir başka kaynakta referans verilmeyen bir görsel için data URI akıl yürütülebilir. Aynı görselin 10 farklı sayfada göründüğü durumda, harici dosyanın cache edilmesi toplam transfer yükünü dramatik biçimde düşürür.

CDN varlığı denklemi değiştirir. Görsel bir CDN edge node'undan sunuluyorsa HTTP isteği zaten coğrafi olarak yakın bir noktadan karşılanır; gecikme değerleri düşer. Base64 ile bu avantajı devre dışı bırakmak ölçülebilir bir geri adımdır. CDN yoksa ve kaynak sunucunun latency'si yüksekse, küçük varlıklar için data URI hesap verebilir.

Altyapı protokolü kararı doğrudan etkiler. HTTP/2 veya HTTP/3 aktifse, çoğullama nedeniyle ek bağlantı maliyeti fiilen sıfıra yakındır. HTTP/1.1 üzerinde çalışan ve CDN kullanmayan bir yapıda, 10-15 adet küçük ikonun sprite veya data URI ile birleştirilmesi ölçülebilir bir kazanç sağlayabilir; ancak bu konfigürasyonlar giderek azalmaktadır.

HTTP/1.1 artık çoğunlukla istisnadır.

Resim formatı da denklemde yer alır. SVG dosyaları zaten metin tabanlı XML yapısında olduğundan base64 encode'u fazladan bir katlama katmanı ekler; SVG'yi doğrudan <img> veya satır içi olarak yerleştirmek çoğu durumda daha az payload üretir ve tarayıcı ayrıştırması daha erken tamamlanır. PNG ve JPEG gibi binary formatlar için %33 artış tam olarak geçerlidir; WebP veya AVIF gibi modern formatlarda orijinal dosya zaten daha küçük olduğundan mutlak byte farkı küçülür, oran değişmez. Yani format optimizasyonu ile base64 kararı birbirinden bağımsız iki eksen oluşturur; biri diğerini telafi etmez.

Pratik bir kontrol yöntemi şöyledir: encode etmeden önce hedef dosyanın sıkıştırılmış boyutunu ölçün, ardından base64 string'inin GZIP sonrası boyutunu karşılaştırın. İki değer arasındaki fark, data URI kullanımının gerçek ağ maliyetini ortaya koyar. Çoğu geliştirici bu karşılaştırmayı atlayarak sezgiye göre karar verir; oysa 10 KB'lık bir PNG için fark onlarca KB'ı bulabilir ve sayfanın toplam payload'ını anlamlı biçimde artırır. Ham base64 string'ini yapıştırarak boyut ve format bilgisini anında görmek, bu kararı veriye dayandırmanın en kısa yoludur.

%33 büyüme sabit ve kaçınılmazdır; değişken olan, bu maliyetin hangi bağlamda kabul edilebilir olduğudur. HTTP isteği sayısı, cache ömrü, tekrar kullanım sıklığı ve altyapı protokolü bir arada değerlendirildiğinde karar çoğunlukla harici dosya lehine kapanır; istisnalar küçük ve sayılıdır. Base64'ü seçmek için somut bir gerekçe yoksa varsayılan tercih harici dosya olmalıdır.