Responsive images denetimi size aslında ne söylüyor
Denetim, gönderdiğiniz dosyayı cihazın ihtiyacı olan pikselle karşılaştırır: layout genişliği çarpı piksel oranı. Raporu okumanın ve düzeltmenin yolu.
Performans raporu, görselleri doğru boyutlandırmakla ilgili bir başlığın altına üç dosya sıralar ve her birinin yanına kaç kilobayt kazanabileceğinizi yazar. Görseller önünüzdeki ekranda gayet doğru görünür, genişlik merdiveni yerindedir, srcset doludur. Denetim sizin ekranınızdan bahsetmiyor. Tek bir taklit cihazdan, tek bir layout genişliğinden ve tek bir aritmetik karşılaştırmadan bahsediyor. Hangi üç sayıyı kullandığını öğrendiğiniz anda rapor bir görüş olmaktan çıkar.
Denetim gerçekte neyi karşılaştırıyor
Araç, sayfadaki her görsel için üç değer alır:
- Görselin çizildiği kutunun layout sonrası CSS piksel cinsinden genişliği.
- Taklit edilen cihazın piksel oranı.
- Gerçekten indirilen dosyanın kendi genişliği.
İlk ikisini çarparak cihazın gösterebileceği gerçek piksel sayısını bulur, bunu üçüncüyle karşılaştırır ve aradaki farkı kazanabileceğiniz byte'a çevirir. Denetimin tamamı budur. Bu bir israf raporudur, doğruluk hükmü değil.
İnsanı en çok şaşırtan örnek şöyle işler. Mobil profilde viewport 412 CSS piksel genişliğindedir. Sayfanın iki yanında 24 piksel boşluk vardır, yazı kolonu daha da dardır, yani görsel 344 piksel olarak yerleşir. Taklit edilen piksel oranı 1,75'tir. Cihazın gösterebileceği genişlik 344 çarpı 1,75, yani yaklaşık 602 pikseldir. Gelen dosya ise 720 piksel geniştir. Gösterilemeyen 118 piksellik sütun israf sayılır ve görsel işaretlenir.
Bu aritmetikten iki sonuç çıkar. Kimsenin dokunmadığı bir görsel, sırf layout değiştiği için işaretlenebilir, çünkü eklenen boşluk kolonu daraltır. Ve telefonun 412 piksel olması neredeyse önemsizdir, önemli olan kutu ile piksel oranıdır.
Denetimin bir de eşiği vardır: hesaplanan kazanç birkaç kilobaytın altında kalıyorsa görsel listeye hiç girmez. Aynı şablondaki iki görselden birinin işaretlenip diğerinin sessizce geçmesinin sebebi genelde budur. Zaten hafif bir avatarın oranı 1,6 olsa da kimseyi ilgilendirmez, 300 kilobaytlık bir hero'nun 1,2'lik oranı ise listeye girer. Rapora düzeltilecek hatalar listesi gibi değil, büyüklük sırasına dizilmiş bir israf tablosu gibi bakın.
sizes ve srcset gerçekte nasıl çalışıyor
w tanımlayıcılı srcset elinizdeki dosyaları anlatır. sizes ise görselin kaplayacağı kutuyu anlatır. Tarayıcının ikincisine ihtiyacı vardır, çünkü dosyayı layout'u bilmeden çok önce seçer.
<img
src="/img/ornek-720.jpg"
srcset="/img/ornek-400.jpg 400w,
/img/ornek-560.jpg 560w,
/img/ornek-720.jpg 720w,
/img/ornek-960.jpg 960w,
/img/ornek-1280.jpg 1280w"
sizes="(min-width: 960px) 600px, (min-width: 640px) 60vw, calc(100vw - 48px)"
width="1280" height="720" alt="Değişiklik öncesi ve sonrası sipariş akışı">Preload scanner bu satırları HTML hâlâ ayrıştırılırken, stil dosyası uygulanmadan önce görür. sizes içindeki koşulları viewport'a göre değerlendirir, CSS piksel cinsinden bir genişlik bulur, bunu cihazın piksel oranıyla çarpar ve sonucu karşılayan en küçük adayı alır. Bizim telefonda calc(100vw - 48px) 364 verir, 1,75 ile çarpılınca 637 olur, tarayıcı da 720'lik dosyayı indirir. Yeterince yakın, denetim de büyük ihtimalle sessiz kalır.
sizes yazmazsanız tarayıcı 100vw varsayar. Bu da 412 çarpı 1,75, yani 721 eder ve 344 piksellik kutu için 960'lık aday indirilir. Bu nitelik, tarayıcının doğrulama imkânı olmayan bir sözdür ve yanlış verilmiş bir söz, srcseti kusursuz olan sayfaların denetimden kalmasının en yaygın sebebidir.
Yanında taşınmaya değer iki ayrıntı daha var:
xtanımlayıcıları yalnızca layout genişliği sabit olan görseller içindir, logo veya avatar gibi. Genişlik viewport'a bağlıysawvesizeskullanın.- Daha büyük bir aday zaten cache'teyse tarayıcı küçüğünü indirmek yerine onu kullanabilir. Cache temizlemeden yapılan elle test size yanlış hikâyeyi anlatır.
Nasıl görülür
Dosya adlarını okuyup akıl yürütmeyin. Denetimin kullandığı genişlikte, cihaz taklidi açıkken sayfanın kendisine sorun. devicePixelRatio ve clientWidth böylece taklit edilen değerleri bildirir:
console.table([...document.images].map((i) => ({
dosya: i.currentSrc.split('/').pop(),
kutu: i.clientWidth,
gereken: Math.round(i.clientWidth * devicePixelRatio),
gelen: i.naturalWidth,
oran: +(i.naturalWidth / Math.max(1, i.clientWidth * devicePixelRatio)).toFixed(2),
})));Oranı 1,2'nin üstünde olan her satır denetimin şikâyetinin tek satırlık halidir. 1'in altında olan satır ise daha kötüdür: tarayıcı, yetersiz bir dosyayı esnetiyordur. dosya sütunu hangi adayın seçildiğini söyler, yalan söyleyen bir sizes niteliğini bulmanın en hızlı yolu da budur.
Build tarafında gerçekte hangi genişlikleri yayınladığınıza bakın:
file dist/img/ornek-*.jpg | sed 's/.*, \([0-9]*x[0-9]*\).*/\1/'
# 400x225
# 720x405
# 1440x810Böyle bir merdiven sorunun ikinci yarısıdır. 721 ile 1440 arasında piksele ihtiyacı olan her cihaz 1440'lık dosyayı alır, yani 720'nin dört katı piksel indirir.
Çözüm
İşe sizes ile başlayın, çünkü bedavadır ve çoğu zaman işareti tek başına kaldırır. Onu hafızadan değil CSS'ten yazın, kırılma noktalarını stil dosyasındakiyle aynı sırada ve aynı değerlerle tutun. Layout karmaşıksa yaygın durumu doğru anlatın ve uçlarda küçük bir aşımı kabul edin.
Sonra merdiveni doldurun. Yaklaşık 1,3 katlık adımlar ortalama aşımı küçük tutar:
const genislikler = [360, 480, 640, 840, 1080, 1360, 1680];
for (const w of genislikler) {
await resize(kaynak, w).toFile(`dist/img/${ad}-${w}.jpg`);
}Üç yerine yedi dosya israf gibi duruyor ama değil: her ziyaretçi yine tek dosya indirir ve build bunları saniyeler içinde üretir. Tek gerçek maliyet depolama ile biraz uzayan srcset metnidir, o da sıkıştırıldığında neredeyse hiçbir şey etmez.
Aynı değişikliğe üç şey daha girer:
- Öğedeki
widthveheightniteliklerini koruyun ki dosya gelmeden kutu ayrılsın. Yer ayırmak, yedek font metriklerini eşlemekle aynı disiplindir ve aynı tür kaymayı ortadan kaldırır. - İlk viewport'taki görseli yüksek öncelikli işaretleyin, asla lazy bırakmayın. En büyük görseli tembel yüklemek, raporun ölçtüğü boyamayı geciktirir.
srcniteliğini orta bir genişliğe bırakın kisrcseti yok sayan bir istemci de makul bir şey alsın.- Format seçimini de aynı adımda halledin.
pictureiçindetypeile modern formatı önce sunup eskisini yedek bırakmak merdivenle birlikte çalışır, aynısizesniteliğini paylaşır ve iki işi iki ayrı sefere bölmenizi engeller.
Çalıştığını nasıl doğrularsınız
Konsol parçasını aynı taklit genişlikte tekrar çalıştırın. Cevap oran sütunundadır:
dosya kutu gereken gelen oran
ornek-640.jpg 344 602 640 1.06
ornek-1080.jpg 768 1344 1360 1.01Sonra pencereyi yavaşça genişletip kırılma noktaları geçtikçe currentSrc değerinin değiştiğini izleyin. Hiç değişmiyorsa ya tarayıcı cache'teki adayı kullanıyordur ya da sizes içinde eşleşen bir koşulunuz yoktur. Denetimi aynı profilde, boş cache ile tekrarlayın ve puanı değil, raporlanan kazancı karşılaştırın.
Nelere dikkat etmeli
- Sert kenarlardan oluşan işlerde denetim yanılır. Halftone noktaları, çizgi işleri, kodlar, ince cetveller ve içinde metin geçen ekran görüntüleri tarayıcı küçülttüğünde dağılır, hafif yumuşayan bir fotoğrafta olmayan biçimde. Her şeyin modern olduğu bir sitede bazı görsellerin hâlâ PNG kalmasının sebebi de budur.
- İşarete, cihazın ihtiyacından küçük dosya göndererek cevap vermeyin. Bulanık bir hero görseli 30 kilobayttan kötü bir sonuçtur ve aynı rapor bunu size hiç söylemez.
sizesile CSS zamanla birbirinden ayrılır. Kolonu daraltan bir yeniden tasarım eski niteliği yerinde bırakır ve bedelini her ziyaretçi öder. Mümkünse niteliği layout ile aynı değerlerden üretin.- Tek bir taklit cihaz tek bir veri noktasıdır. Telefon profilinde işaretlenen bir hero, o sayfanın okurlarının çoğunun bulunduğu masaüstünde tam olarak doğru olabilir.
- Piksel oranı üç olan cihazlar var, merdiveni sınırlamak onlarda büyütme demektir. Bu, fotoğraflarda genelde doğru, içinde metin geçen görsellerde yanlış bir takastır.
Denetim aritmetiktir ve üç girdiyi birden görebildiğinizde aritmetikle tartışmak kolaydır. Çoğu zaman dürüst çözüm, doğruyu söyleyen bir sizes niteliği ve merdivene eklenen iki dosyadır. Bu bir öğleden sonra sürer ve bir daha açılmaz. Geri kalan zamanlarda araç, hüküm veremeyeceği bir şeyi ölçüyordur ve doğru cevap dosyanın neden o boyutta olduğunu yazıp yola devam etmektir. Raporlar tam olarak neyi karşılaştırdıklarını anladığınız kadar işe yarar; bir animasyonun boyama metriğini mahvetmesi de önünüzdeki sayfa kusursuz görünürken olur.
Sorular ve cevaplar
- Sadece 412 piksel genişliğindeki telefonda 720 piksellik görsel neden işaretleniyor?
- Çünkü karşılaştırma ekran genişliğine karşı yapılmıyor. Araç, görselin çizildiği kutunun genişliğini alır, taklit edilen cihazın piksel oranıyla çarpar ve sonucu dosyanın gerçek genişliğiyle karşılaştırır. Piksel oranı 1,75 olan bir cihazda 344 piksellik kolona oturan görselin ihtiyacı yaklaşık 602 pikseldir, yani 720 piksellik dosya kimsenin göremeyeceği piksel taşır.
- sizes niteliği tam olarak ne yapar?
- Tarayıcıya, layout daha ortada yokken görselin ne kadar geniş çizileceğini söyler. Preload scanner bunu HTML hâlâ ayrıştırılırken okur, değeri cihazın piksel oranıyla çarpar ve srcset içinde bu sayıyı karşılayan en küçük adayı seçer. sizes yazmazsanız tarayıcı tüm viewport genişliğini varsayar, bu da telefonda genelde listedeki en büyük dosyayı indirmek demektir.
- Ara genişlik mi eklemeliyim yoksa tek küçük dosya mı yeter?
- Ara genişlik. 720'den 1440'a atlayan bir merdiven, 800 piksele ihtiyacı olan her cihazı 1440'ı indirmeye ve dört katı piksel ödemeye zorlar. Yaklaşık 1,3 katlık adımlar aşımı küçük tutar. Fazladan dosyaların servis maliyeti yoktur, çünkü her ziyaretçi yine tek bir dosya indirir.
- Responsive images denetimini ne zaman görmezden gelmeliyim?
- Görsel fotoğrafik detaydan değil sert kenarlardan oluşuyorsa. Nokta desenleri, çizgi işleri, kodlar, ince cetvelli diyagramlar ve içinde metin geçen ekran görüntüleri tarayıcı küçülttüğünde bozulur ve bozulma, hafif yumuşamış bir fotoğrafta görünmeyecek kadar belirgin olur. Büyük dosyayı koruyun, sebebini yazın ve tasarrufu başka yerde arayın.