- GitHub Pages Brotli desteklemediği için, HTML’i kayıpsız WebP görüntüsü olarak kodlayıp tarayıcının görüntü çözücüsü ve JavaScript ile geri yükleyerek aktarılan veri miktarını azaltmaya yönelik bir deney
- WASM Brotli çözücüsü
71 KiB~200 KBek maliyet getiriyor; Compression Streams API ise yalnızcagzip,deflate,deflate-rawdesteklediğinden Brotli çözmeyi dolanmak için uygun bir yol olmakta zorlanıyor - VP8L kayıpsız WebP; tahmin dönüşümü, 16x16 blok başına Huffman ağacı yeniden kullanımı ve color cache sayesinde metin benzeri verilerde de gzip’ten daha küçük sonuçlar üretebiliyor
- Test HTML’i
439,478bayttan gzip ile94,683bayta, WebP ile43,182bayta kadar düştü; Brotli’nin37 KiBsonucundan büyük olsa da gzip’e göre yaklaşık 2,2 kat daha küçüktü - Canvas 2D’nin anti-fingerprinting gürültüsü, WebGL
readPixelsdeğişiklikleri, ilk baştaki boş ekran ve kaydırma konumunu geri yükleme sorunları nedeniyle gerçek uygulamadan çok tarayıcı kısıtlarını ortaya koyan bir hack niteliğinde
GitHub Pages’te Brotli kullanılamaması sorunu
- Sayfa yükleme süresini azaltırken HTTP sıkıştırması, HTML minify’dan daha büyük etki yaratır
- HTTP,
Content-Encodingbaşlığıyla gzip ve Brotli destekler- gzip ucuzdur, bu yüzden genellikle varsayılan olarak etkinleştirilir
- Brotli’nin sıkıştırma oranı genellikle gzip’ten iyidir ama çok daha yavaştır
- GitHub Pages Brotli desteklemediği için, sitenin en uzun yazısı olan
Recovering garbled Bitcoin addresses, Brotli ile37 KiBolabilecekken gzip ile92 KiBolur - Bu fark yüzünden yükleme süresi gereksiz yere 2,5 kat artar
İlk akla gelen alternatif ve tıkanılan noktalar
- GitHub önceden sıkıştırılmış Brotli dosyalarının yüklenmesini ve sunulmasını destekleseydi sorun aşılabilirdi, ancak böyle bir özellik sunulmuyor
- İstemci tarafında JavaScript ile doğrudan açma yaklaşımında WASM çözücünün boyutu nedeniyle avantaj azalır
- brotli-dec-wasm yaklaşık
200 KB - tiny-brotli-dec-wasm
71 KiB - Karşılaştırma gzip
92 KiBile Brotli gövdesi37 KiB + 71 KiBhâline gelir ve kazanç ortadan kalkar
- brotli-dec-wasm yaklaşık
- Tarayıcının HTTP yığınında Brotli çözücüsü vardır, ancak Compression Streams API içindeki DecompressionStream yalnızca
gzip,deflate,deflate-rawkabul eder gzipZopfli ile önceden sıkıştırılsa bile86 KiBolur, yani Brotli’den daha büyük kalır
Görüntü biçimini sıkıştırma konteyneri gibi kullanmak
- Tarayıcılar görüntüleri çözebildiği için, veriyi görüntü piksellerine koyup Canvas API ile tekrar okursanız yeni bir açma mantığı eklemeniz gerekmez
- GIF, veriyi row-major sırayla açtıktan sonra LZW uygular; ancak gzip’in DEFLATE’i LZW’nin yerini almak üzere tasarlanmış bir yöntem olduğundan kazanç beklemek zordur
- PNG DEFLATE kullanır, fakat pikselin ham hâlini değil, önce komşu piksellerle farkı sıkıştıran bir tahmin dönüşümü uygular
- Örnek:
[a, b, c, d]yerine[a, b-a, c-b, d-c]sıkıştırılır - Tahmin değeri ile gerçek değer arasındaki fark ne kadar küçükse Huffman sıkıştırması için o kadar avantajlıdır
- Örnek:
- Deneyin özü, kayıpsız WebP olan VP8L’yi genel bayt verisi sıkıştırma amacıyla kullanmaktır
VP8L’in gzip’ten farkları
- WebP’nin kayıplı ve kayıpsız varyantları vardır; burada yalnızca kayıpsız biçim olan VP8L ele alınır
- VP8L, PNG gibi tahmin dönüşümü kullanır, ancak DEFLATE yerine Google’ın yaptığı DEFLATE benzeri bir yöntem kullanır
- DEFLATE dosyayı birden çok parçaya bölebilir ve her parça için uygun Huffman ağaçları kullanabilir
- JavaScript, SVG ve markup tek bir HTML içinde karıştığında farklı ağaçlar daha avantajlı olabilir
- VP8L keyfi büyüklükte bir Huffman ağacı tablosu tanımlar ve her 16x16 piksel bloğu için farklı bir ağaç kullanabilir
- JavaScript’ten sonra CSS, ardından tekrar JavaScript geldiğinde DEFLATE benzer ağaçları birden fazla kez kodlayabilir
- VP8L ağaçları yeniden kullanabildiği için ağaçları daha sık ve daha düşük maliyetle değiştirebilir
- VP8L’in color cache özelliği, belirli niteliklere sahip yakın geçmişteki pikselleri kopyala anlamında değerleri kısa ifade edebilir
İlk WebP sıkıştırma deneyi
- Test dosyası
Recovering garbled Bitcoin addressesHTML’idir- Orijinal boyut:
439,478bayt gzip --best:94,683bayt
- Orijinal boyut:
- Rust’taki webp crate’i ile baytlar grayscale RGB görüntüsüne dönüştürülüp kayıpsız WebP olarak sıkıştırıldı
- Grayscale kullanılmasının nedeni WebP’nin
subtract greendönüşümüdür- Grayscale’de G kanalı R/B’den çıkarıldığında R/B fiilen 0 olur
- WebP üç kanalı ayrı Huffman ağaçlarıyla kodladığı için sabit değerli kanallar
O(1)alana yakın hâle gelir
- Başta
1xNgörüntü yapılmak istendi, ancak WebP en fazla16383x16383desteklediğindenVP8_ENC_ERROR_BAD_DIMENSIONhatası oluştu 16383xNbiçimine ayarlanınca sonuç45,604bayt oldu; gzip’ten 2 kat küçük ve bzip2’nin49,764baytından da küçüktü
WebP’ye özel ayarlamalar
- Geniş görüntüde row-major sıra kullanılırsa 16x16 blok içine girdide birbirinden uzak baytlar karışır
- Görüntü biçimi dikey olarak uzun
27x16383yapıldığında sıkıştırma sonucu43,232bayta düştü cwebp’nin sıkıştırma performansı ayarı olan method0~6arasında karşılaştırıldı- method 0:
48,902 - method 1:
43,546 - method 2:
43,442 - method 3:
43,292 - method 4:
43,232 - method 5:
43,182 - method 6:
43,182
- method 0:
- method
5, method6ile aynı boyutu üretirken daha hızlı seçenek olarak seçildi - Bu durumda WebP, gzip’ten 2,2 kat küçük ve Brotli’den 1,2 kat büyüktü
Birden çok dosyada benchmark
- Karşılaştırma verileri snappy testdata, Canterbury Corpus ve Large Corpus ile 2 SVG dosyasıydı
- Karşılaştırılan biçimler
gzip --best,brotli --best,bzip2 --bestve WebP sıkıştırma script’iydi - WebP, çok küçük dosyalar olan
grammar.lsp,xargs.1ve bazı istisnalar dışında neredeyse her zaman gzip’ten daha iyiydi - İstisnalar
kennedy.xlsvepaper-100k.pdfidipaper-100k.pdf,19 KBXML’in ardından sıkıştırılmış veri içerdiği için fiilen küçük verinin ölçüldüğü bir durumdurkennedy.xlsiçin Brotli/bzip2 göreli performansı da gariptir; yakın konumlarda çok sayıda heterojen veri bulunduğundan sıkıştırıcıların işlemesi zor bir dosya olabilir
- WebP genel olarak bzip2’den biraz daha kötüydü, ancak bazı durumlarda onu geçti
- WebP,
fireworks.jpeggibi neredeyse tekdüze rastgele blob’a yakın istisnalar dışında her zaman Brotli’den kötüydü - Büyük plain-text verilerde gzip’e kıyasla ölçülebilir iyileşme sağladı
- SVG dosyalarında da iyileşme vardı
html_x_4içinde WebP%3,3sıkıştırma oranı kaydetti; Brotli’nin%2,8sonucundan kötü olsa da gzip’in%13sonucundan belirgin biçimde iyiydi
JavaScript ile geri yükleme
- WebP çözmenin kendisi
fetch,createImageBitmap,OffscreenCanvas,getImageData,TextDecoderile uygulanabilir - Pikselin R kanalı orijinal HTML baytları olarak kullanılır; bunlar UTF-8 olarak çözüldükten sonra
document.documentElement.innerHTMLiçine yerleştirilir - Canvas API fingerprinting için sık kullanıldığından bazı tarayıcılar
getImageDatasonucuna gürültü ekler- Firefox’un strict tracking protection modunda piksellerin %1’den azı etkilenebilir
- HTML’de bu gürültü yazım hataları gibi görünür
- WebGL’in
readPixelskullanılması o dönemde gürültüsüz çalışıyordu- WebGL dokuları güvenilir biçimde yalnızca
2048x2048boyutuna kadar desteklediğinden boyut sınırını yeniden ayarlamak gerekir - Bu geri yükleme kodu minify sonrası yaklaşık
550bayttı
- WebGL dokuları güvenilir biçimde yalnızca
- WebP ve kod birlikte
44 KiBoldu; gzip92 KiB, Brotli37 KiBile karşılaştırıldı - 15 Nisan 2026’dan sonra Firefox
readPixelsiçin de anti-fingerprinting eklediğinden, bu yöntem artık aynı hâliyle çalışmıyor
Ekran titremesi ve kaydırma sorunu
awaitpromise tabanlı işlendiği için, WebP indirmesi bitmeden tarayıcı script çalışmasının bittiğine karar verir- DOM hâlâ boş olduğundan kullanıcı kısa süreliğine boş beyaz ekran görür
- Hafifletme olarak stil ve sayfanın üst kısmındaki yaklaşık
8 KiBgzip HTML içinde bırakılıp yalnızca viewport altındaki içerik WebP ile sıkıştırılabilir - Yenileme sırasında kaydırma konumunun geri yüklenmesi de sorun olur
- Örneğin
Y = 5000pxkonumundayken sayfa yenilendiğinde sayfa yüksekliği0pxise konum sıfırlanır - Çok büyük geçici bir
diveklemek yardımcı olabilir
- Örneğin
- Geçerli belgeyi yeni belgeyle değiştirmeden güncelleyebilmek için
document.writeyerinedocument.documentElement.innerHTMLataması yapılmalıdır
WebP’yi doğrudan JavaScript içine koymak
- Gecikmeyi biraz daha azaltmak için WebP JavaScript’in içine doğrudan gömülebilir
- En basit yöntem base64 data URL’dir
- base64 orijinal boyutu
1,33 katartırır, ancak gzip bu artışın neredeyse tamamını dengelercompressed.webpbase64 yapılınca57,576bayt olur- Bu, gzip
--bestile sıkıştırılınca43,519bayta iner
- WebP gibi sıkıştırılmış blob’lar neredeyse tekdüze rastgele veridir; base64’ün 8-bit’ten 6-bit’e dönüşüm sonucunda gzip’in Huffman ağacı fiilen ters dönüşüm gibi çalışır
- Unicode ve UTF-16 da kullanılabilir, ancak base64 yeterli bir ilk çözüm olarak kalır
Gerçek uygulama ve sonraki durum
- Yazının yazıldığı sırada bu sayfanın kendisi, eski tarayıcılar veya JavaScript’in kapalı olduğu ortamlar dışında “Fool me twice” bölümünden itibaren WebP ile sıkıştırılmıştı
- Sayfanın WebP görüntüsü gerçek kodda dikey olarak uzun ve dardı, ancak güzel görünmesi için kare bir WebP örneği de sağlanmıştı
- Görüntüdeki parlak üst ve alt kısımlar metin ve koddu; yaklaşık 1/5 noktasındaki taralı alan diyagram, karanlık alanların çoğu ise diyagram içindeki metindi
- Gerçek tasarruf sınırlıydı
- Önceki gzip sayfası:
88 KiB - WebP uygulandıktan sonra gzip sayfası:
83 KiB - Brotli tahmini:
69 KiB
- Önceki gzip sayfası:
- 15 Nisan 2026’dan sonra Firefox ziyaretçilerine bozuk içerik görünmemesi için şu anda sıkıştırılmamış sayfaya geçildi
- Rust kodu, corpus ve diğer dosyalar GitHub üzerinde yayımlandı
1 yorum
Hacker News yorumları
Gecikmeyi yok sayarsanız öyle olabilir, ama pratikte yükleme süresini ancak %0,001 civarında artırıyor gibi görünüyor.
Boyuttaki artış, gidiş-dönüş gecikmesine kıyasla anlamlı değil; 55KiB daha az aktararak kazanılan zamandan daha fazlası sıkıştırmayı açmaya harcanabilir.
İlginç bir deney olsa da bu durumda kullanıcı deneyiminin daha da kötüleşmesi muhtemel; hız neredeyse aynı kalırken yalnızca uyumluluk düşecek gibi.
Sorun şu: TFA yazarı gibi 100KB’ı 50KB’a indirmeye uğraşanlar da var, ama ben dolaşım verisiyle yalnızca bir restoranın çalışma saatlerine bakmak isterken hiç çekinmeden onlarca MB görüntü gönderen yerler de var.
Kaynak bilinci var, fakat ne yazık ki çok dengesiz dağılmış durumda.
Bağlantı koparsa her şeyi kaybedersiniz; indirilen kısmı bile okumanız imkânsız hâle gelir.
Normal bağlantılarda fark anlamsızdır; 50KB’ın önemli olacağı kadar çok yavaş ya da kararsız bağlantılarda ise bu yöntem kesinlikle daha kötü olur. İlginç bir deney, ama sitelerde uygulanmasa iyi olur.
Symbols-2048-em%20Nerd%20Font%20Complete.woff2dosyası var; bu da farkı neredeyse tamamen kapatıyor.2,5 kat fark olmayabilir, ama %0,001 de değil.
Kayıplı ağlarda fark olabilir, ama emin değilim.
readPixels’ın neden parmak izi önleme kapsamında olmadığını bilmiyorum. Sayfanın tamamına neredeyse görünmez yazım hataları serpiştirilmeyeceği için benim açımdan sorun yok.gzip’lenmiş HTML’de yalnızca stiller ve sayfanın üst kısmındaki yaklaşık 8KiB bırakılıp, görüntü alanının altındaki içeriğin WebP ile sıkıştırıldığı kısmı görünce metnin neden rastgele bir cümleden sonra birden kesilip ardından boş sayfa geldiği açıklığa kavuştu.
LibreWolf kullandığım için WebGL kapalı; WebGL gerektiren rastgele web oyunlarını Chromium ile açıyorum. WebGL’i açınca yazı düzgün çalıştı ve dürüst olmak gerekirse oldukça temiz bir teknik.
WWW, sıradan HTML ile başlayıp kademeli olarak geliştirilerek evrensel erişilebilir olmalı.
Web tarayıcılarında Brotli’yi doğrudan kullanmak da mümkün, ama elbette kısıtları var.
2022 JS1024 başvurusu [1] bence bu kavramın ilk gösterimiydi; keyfî sıkıştırma için bir kavram kanıtı kodu da var. Ne yazık ki asıl amaç olan boyut kodlaması için uygun değildi.
Temel kısıt, fiilen ASCII karakterlerle sınırlı olması ve bariz nedenlerle render yığınına çok hassas olması. Şu anda Firefox’ta çalışmıyor gibi görünüyor.
[1] https://js1024.fun/demos/2022/18/readme
[2] https://gist.github.com/lifthrasiir/1c7f9c5a421ad39c1af19a9c...
Yalnızca Brotli’nin başlangıçta tasarlandığı WOFF2 yazı tipi dosya biçimini kullanmak mümkün; fakat bundan yararlanmak için eksiksiz bir yazı tipi dosyası oluşturmak gerekiyor.
Güncel tarayıcılar, güvenilmeyen yazı tipi dosyalarını doğrudan sisteme koymak çok tehlikeli olduğundan genellikle yazı tiplerini OpenType Sanitizer (OTS) ile temizliyor; bu yüzden hem OTS’nin kabul edeceği kadar düzgün hem de istenen bayt dizisini içinde taşıyıp çıkarılabilir kılan bir WOFF2 dosyası üretmek gerekiyor.
Birçok başarısız denemeden sonra, neredeyse kısıtsız biçimde 2 baytlık işaretli tamsayı dizileri olarak kodlanan glif genişliklerine, yani advance değerlerine karar verilmesi fikri harika.
Chromium tarafı uzun süre engelliyordu, ama zstd de artık web’e giriyor. Sonunda Chrome’a girdi; artık sadece Safari’nin yetişmesi kaldı.
Batch Compress'i (https://batchcompress.com/en) geliştiriyorum ve kısa süre önce WebP desteği ekledikten çok geçmeden varsayılan olarak değiştirdim
Bildiğim kadarıyla zaten web sıkıştırma araçları arasında en küçük JPEG'leri üretiyorduk; WebP ise JPEG'in yaklaşık %50'si boyutunda çıkıyordu. Desteği ekledikten kısa süre sonra varsayılanı değiştirmek kolay bir karardı
Sitenin epey kullanıcısı olduğu için WebP'yi varsayılan yaptıktan sonra biraz şikâyet gelir diye düşünmüştüm, ama aradan yaklaşık bir ay geçmişken WebP ile ilgili yalnızca bir soru ya da şikâyet geldi
Artık neredeyse tüm araçlar ve tarayıcılar WebP'yi destekliyor gibi. Yakın zamanda WebP görsel yüklemelerini düzgün işleyemediği için sonraki adımı engelleyen yalnızca bir web sitesi gördüm; bugünlerde neredeyse her yerde iyi destekleniyor
JPEG iyi sıkıştırılıp optimize edilirse WebP'nin çok gerisinde kalmamalı
JPEG'den neredeyse farksız görünen bir WebP üretip dosya boyutunu her zaman küçültebilirsiniz; ama neredeyse aynı görünen bir JPEG'e yeniden sıkıştırınca da aynı şey olur
Bu, tüm kayıplı sıkıştırma codec'lerinin özelliği; kalite yükseldikçe dosya boyutu üstel olarak büyüdüğü için insanlar, neredeyse görünmez çok küçük bir kalite düşüşünün bile dosya boyutunu ne kadar değiştirebildiğine hep şaşırıyor
WebP, karanlık alanlardaki ayrıntıları mahveden berbat varsayılanlarıyla kötü şöhretliydi
Kaynağa bakarken doctype bildiriminde bir boşluğun eksik olduğunu gördüm. Mevcut biçim hatalı; arada boşluk olmalı
DOCTYPEboşluğunu atlamak daha kısa yapabilirKesin konuşursak geçerli HTML değil, ama yine de standart modunu başarıyla tetikliyor
Referans: https://GitHub.com/kangax/html-minifier/pull/970 / https://HTML.spec.WHATWG.org/multipage/parsing.html#parse-er...
Ben de bu numarayı https://FreeSolitaire.win üzerinde kullanıyorum
Mümkün olduğunca çok şeyi kaldıran bir minifier çıktısı gibi görünüyor [0]
0: https://github.com/KTibow/KTibow/issues/3#issuecomment-23367...
Bu numarayı daha önce denemiştim. Tuhaf şekilde ne için kullandığımı hatırlamıyorum; muhtemelen mümkün olup olmadığını görmek içindi ve buraya da yorum bırakmıştım: https://gist.github.com/gasman/2560551?permalink_comment_id=...
Eski bir prototip de buldum; sanırım sadece testti: https://retr0.id/stuff/bee_movie.webp.html
Artık eklenti değil uzantı denen, betik enjekte etmeye benzer şeyler bunlar; neyse, başlangıçta “çöp”ü iletip arkasına JS ekleyerek sayfaya geri döndürme yaklaşımı ilginç
İçimdeki güvenlik meraklısı, yorum formu gibi kullanıcı tarafından sağlanan veriler olduğunda bunun saldırıya açık hale gelip gelmeyeceğini merak ediyor
Birisi yoruma koyulacak bayt dizisini bulup, sıkıştırmadan sonra benim betiğimden önce yer alarak çalıştırılan bir
scriptetiketine dönüşmesini sağlayabilir mi diye düşünüyorumWebP kayıpsızın PNG'ye kattıklarının çoğu kodlamadan çok modellemeyle ilgili; bu tür metin sıkıştırma ise WebP'nin yalnızca kodlama kısmını kullanıyor
Google Fonts'u çıkarmak da sayfa yüklenme süresini biraz iyileştirir. Çünkü uzak bir sunucudan yükleniyor ve ek el sıkışma gerektiriyor
Bu sayfa en azından Sailfish OS tarayıcısında bozuluyor. Şu paragraftan sonra uzun bir boş alan var
“Alright, so we’re dealing with 92 KiB for gzip vs 37 + 71 KiB for Brotli. Umm…”
Yine de gzip ve Brotli HTML sıkıştırmasının ek yükü, günümüz web sitelerinin kullandığı JS, görsel ve video miktarına kıyasla hiçbir şey
Şahsen bu formatı pek sevmiyorum. Bir görsel kaydedip WebP olarak kaydedildiğinde, web tarayıcısı dışında destekleyen pek yer olmadığı için düzenlemeden ya da anlamlı biçimde kullanmadan önce dönüştürmem gerekiyor
Sanki sadece ek bir adım dayatıyor gibi
Yine de destek daha da artarsa sorun olmayabilir. 20 yılda bir yeni format çıkmasına katlanabilirim
.webmise ortadan kalksa olur