Resim bileşeni, performansla ilgili en iyi uygulamaları içerir ve resimleri optimize etmek için kullanıma hazır bir çözüm sağlar.
Resimler, web uygulamaları için performans sorunlarının yaygın bir kaynağıdır ve optimizasyon için temel odak noktalarından biridir. Optimize edilmemiş resimler sayfa şişirilmesine katkıda bulunur ve 90.th yüzdelik dilimde bayt cinsinden toplam sayfa ağırlığının% 70'inden fazlasını oluşturur. Resimleri optimize etmenin birden fazla yolu vardır. Bu nedenle, performans çözümlerinin varsayılan olarak yerleşik olduğu akıllı bir "resim bileşeni" gerekir.
Aurora ekibi, bu tür bir bileşen oluşturmak için Next.js ile çalıştı. Amaç, web geliştiricilerinin daha da özelleştirebileceği optimize edilmiş bir resim şablonu oluşturmaktı. Bu bileşen iyi bir model görevi görür ve diğer çerçevelerde, içerik yönetim sistemlerinde (İYS) ve teknoloji gruplarında resim bileşenleri oluşturmak için bir standart belirler. Benzer bir Nuxt.js bileşeni üzerinde birlikte çalıştık ve gelecek sürümlerde resim optimizasyonu için Angular ile çalışıyoruz. Bu yayında, Next.js resim bileşenini nasıl tasarladığımız ve bu süreçte edindiğimiz dersler ele alınmaktadır.
Resim optimizasyonuyla ilgili sorunlar ve fırsatlar
Resimler yalnızca performansı değil, işletmeyi de etkiler. Bir sayfadaki resim sayısı, web sitelerini ziyaret eden kullanıcılara ilişkin ikinci dönüşüme dair en büyük ön göstergedir. Kullanıcıların dönüşüm gerçekleştirdiği oturumlarda, dönüşüm gerçekleştirmeyen oturumlara kıyasla% 38 daha az resim vardı. Lighthouse, en iyi uygulamalar denetimi kapsamında görselleri optimize etmek ve web temel metriklerini iyileştirmek için birden fazla fırsat listeler. Resimlerin önemli web verilerini ve kullanıcı deneyimini etkileyebileceği yaygın alanlardan bazıları şunlardır:
Boyutlandırılmamış resimler CLS'yi olumsuz etkiler
Boyutları belirtilmeden yayınlanan resimler düzen kararsızlığına neden olabilir ve yüksek bir kümülatif düzen kaymasına (CLS) yol açabilir. img öğelerinde width
ve height
özelliklerini ayarlamak, düzen kaymalarını önlemeye yardımcı olabilir. Örneğin:
<img src="flower.jpg" width="360" height="240">
Genişlik ve yükseklik, oluşturulan resmin en boy oranının doğal en boy oranına yakın olacak şekilde ayarlanmalıdır. En boy oranında önemli bir fark, resmin bozuk görünmesine neden olabilir. CSS'de en boy oranını belirtmenize olanak tanıyan nispeten yeni bir mülk, CLS'yi önlerken resimleri duyarlı bir şekilde boyutlandırmanıza yardımcı olabilir.
Büyük resimler LCP'yi olumsuz etkileyebilir
Resmin dosya boyutu ne kadar büyükse indirme işlemi o kadar uzun sürer. Büyük resim, sayfanın "kahraman" resmi veya görüntü alanındaki en önemli öğe olup Largest Contentful Paint'i (LCP) tetiklemekten sorumlu olabilir. Kritik içeriğin parçası olan ve indirilmesi uzun süren bir resim, LCP'nin gecikmesine neden olur.
Geliştiriciler, daha iyi sıkıştırma ve duyarlı resimler kullanarak çoğu durumda resim boyutlarını azaltabilir. <img>
öğesinin srcset
ve sizes
özellikleri, farklı boyutlarda resim dosyaları sağlamanıza yardımcı olur. Tarayıcı, ekran boyutuna ve çözünürlüğüne göre doğru olanı seçebilir.
Kötü resim sıkıştırma, LCP'ye zarar verebilir
AVIF veya WebP gibi modern resim biçimleri, yaygın olarak kullanılan JPEG ve PNG biçimlerine kıyasla daha iyi sıkıştırma sağlayabilir. Daha iyi sıkıştırma, aynı resim kalitesi için bazı durumlarda dosya boyutunu% 25 ila% 50 oranında azaltır. Bu azaltma, daha az veri tüketimi ile daha hızlı indirme işlemine olanak tanır. Uygulama, bu biçimleri destekleyen tarayıcılara modern resim biçimleri sunmalıdır.
Gereksiz resim yüklemek LCP'ye zarar verir
Sayfa yüklendiğinde, kullanıcıya ekranın alt kısmındaki veya görüntü alanında olmayan resimler gösterilmez. LCP'ye katkıda bulunmamaları ve LCP'yi geciktirmeleri için ertelenebilirler. Bu tür resimleri, kullanıcı ekranı kaydırırken daha sonra yüklemek için geç yükleme özelliğini kullanabilirsiniz.
Optimizasyonla ilgili zorluklar
Ekipler, daha önce listelenen sorunlardan kaynaklanan performans maliyetini değerlendirebilir ve bu sorunları gidermek için en iyi uygulama çözümlerini uygulayabilir. Ancak bu durum pratikte genellikle gerçekleşmez ve verimsiz resimler web'i yavaşlatmaya devam eder. Bunun olası nedenleri şunlardır:
- Öncelikler: Web geliştiricileri genellikle koda, JavaScript'e ve veri optimizasyonuna odaklanır. Bu nedenle, resimlerle ilgili sorunlardan veya resimlerin nasıl optimize edileceğinden haberdar olmayabilirler. Tasarımcılar tarafından oluşturulan veya kullanıcılar tarafından yüklenen resimler, öncelik listesinde üst sıralarda yer almayabilir.
- Kullanıma hazır çözüm: Geliştiriciler resim optimizasyonunun inceliklerini bilse bile, çerçeveleri veya teknoloji yığınları için hepsi bir arada kullanıma hazır bir çözümün olmaması caydırıcı olabilir.
- Dinamik resimler: Uygulamanın parçası olan statik resimlere ek olarak dinamik resimler de kullanıcılar tarafından yüklenir veya harici veritabanlarından ya da içerik yönetim sistemlerinden alınır. Resmin kaynağının dinamik olduğu bu tür resimlerin boyutunu tanımlamak zor olabilir.
- Çok fazla işaretleme: Resim boyutunu veya farklı boyutlar için
srcset
işaretini ekleme çözümleri, her resim için ek işaretleme gerektirir. Bu da can sıkıcı olabilir.srcset
özelliği 2014'te kullanıma sunulmasına rağmen günümüzde web sitelerinin yalnızca%26,5'i tarafından kullanılıyor.srcset
kullanırken geliştiricilerin çeşitli boyutlarda resimler oluşturması gerekir. just-gimme-an-img gibi araçlar yardımcı olabilir ancak her resim için manuel olarak kullanılmalıdır. - Tarayıcı desteği: AVIF ve WebP gibi modern resim biçimleri daha küçük resim dosyaları oluşturur ancak bunları desteklemeyen tarayıcılarda özel işleme tabi tutulmaları gerekir. Resimlerin tüm tarayıcılara sunulması için geliştiricilerin içerik görüşmesi veya
<picture
> öğesi gibi stratejiler kullanması gerekir. - Geç yüklemeyle ilgili sorunlar: Ekranın alt kısmındaki resimler için geç yüklemeyi uygulamak üzere kullanılabilecek birden fazla teknik ve kitaplık vardır. En iyisini seçmek zor olabilir. Geliştiriciler, ertelenen resimleri yüklemek için "ekrandan" en iyi mesafeyi de bilemeyebilir. Cihazlardaki farklı görüntü alanı boyutları bu durumu daha da karmaşık hale getirebilir.
- Değişen ortam: Tarayıcılar performansı artırmak için yeni HTML veya CSS özelliklerini desteklemeye başladığında, geliştiricilerin bunların her birini değerlendirmesi zor olabilir. Örneğin, Chrome Getirme Önceliği özelliğini Kaynak Deneme olarak kullanıma sunuyor. Sayfadaki belirli resimlerin önceliğini artırmak için kullanılabilir. Genel olarak, bu tür iyileştirmelerin bileşen düzeyinde değerlendirilip uygulanması geliştiriciler için daha kolay olur.
Çözüm olarak resim bileşeni
Resimleri optimize etmek için sunulan fırsatlar ve bunları her uygulama için ayrı ayrı uygulamanın zorlukları, resim bileşeni fikrine ulaşmamıza yol açtı. Resim bileşenleri, en iyi uygulamaları kapsayabilir ve zorunlu kılabilir. Geliştiriciler, <img>
öğesini bir resim bileşeniyle değiştirerek görüntü performansı sorunlarını daha iyi ele alabilir.
Geçtiğimiz yıl, Resim bileşenini tasarlamak ve uygulamak için Next.js çerçevesiyle birlikte çalıştık. Next.js uygulamalarındaki mevcut <img>
öğelerinin yerine aşağıdaki gibi doğrudan kullanılabilir.
// Before with <img> element:
function Logo() {
return <img src="/logo.jpg" alt="logo" height="200" width="100" />
}
// After with image component:
import Image from 'next/image'
function Logo() {
return <Image src="/logo.jpg" alt="logo" height="200" width="100" />
}
Bileşen, zengin bir özellik ve ilke grubu aracılığıyla görüntüyle ilgili sorunları genel olarak ele almaya çalışır. Ayrıca geliştiricilerin çeşitli resim gereksinimleri için özelleştirmelerine olanak tanıyan seçenekler de içerir.
Düzen kaymalarına karşı koruma
Daha önce de belirtildiği gibi, boyutlandırılmamış resimler düzen kaymalarına neden olur ve CLS'ye katkıda bulunur. Next.js resim bileşenini kullanırken geliştiricilerin, düzen kaymalarını önlemek için width
ve height
özelliklerini kullanarak bir resim boyutu sağlaması gerekir. Boyut bilinmiyorsa geliştiricilerin, boyutlu bir kapsayıcıda duran boyutsuz bir görüntü sunmak için layout=fill
öğesini belirtmesi gerekir. Alternatif olarak, derleme sırasında sabit diskteki gerçek resmin boyutunu almak ve resme dahil etmek için statik resim içe aktarma işlemlerini kullanabilirsiniz.
// Image component with width and height specified
<Image src="/logo.jpg" alt="logo" height="200" width="100" />
// Image component with layout specified
<Image src="/hero.jpg" layout="fill" objectFit="cover" alt="hero" />
// Image component with image import
import Image from 'next/image'
import logo from './logo.png'
function Logo() {
return <Image src={logo} alt="logo" />
}
Geliştiriciler resim bileşenini boyutlandırılmamış şekilde kullanamazlar. Bu nedenle, tasarım sayesinde geliştiriciler resim boyutlandırmasını dikkate almak ve düzen kaymalarını önlemek için zaman ayırırlar.
Yanıt vermeyi kolaylaştırma
Resimlerin cihazlar arasında duyarlı olmasını sağlamak için geliştiricilerin <img>
öğesinde srcset
ve sizes
özelliklerini ayarlamaları gerekir. Resim bileşeniyle bu çabayı azaltmak istedik. Next.js Image bileşenini, özellik değerlerini uygulama başına yalnızca bir kez ayarlayacak şekilde tasarladık. Bunları, düzen moduna göre Resim bileşeninin tüm örneklerine uygularız. Üç bölümden oluşan bir çözüm önerdik:
deviceSizes
mülkü: Bu mülk, uygulama kullanıcı tabanında ortak olan cihazlara göre kesme noktalarını tek seferlik yapılandırmak için kullanılabilir. Kesme noktaları için varsayılan değerler yapılandırma dosyasına dahil edilir.imageSizes
mülkü: Bu, cihaz boyutu kesme noktalarına karşılık gelen resim boyutlarını almak için kullanılan yapılandırılabilir bir mülktür.- Her resimdeki
layout
özelliği: Bu özellik, her resim içindeviceSizes
veimageSizes
özelliklerinin nasıl kullanılacağını belirtmek amacıyla kullanılır. Düzen modu için desteklenen değerlerfixed
,fill
,intrinsic
veresponsive
'dır.
Responsive veya fill düzen modlarıyla bir resim istendiğinde Next.js, sayfayı isteyen cihazın boyutuna göre sunulacak resmi tanımlar ve resimdeki srcset
ile sizes
öğelerini uygun şekilde ayarlar.
Aşağıdaki karşılaştırmada, düzen modunun farklı ekranlardaki resmin boyutunu kontrol etmek için nasıl kullanılabileceği gösterilmektedir. Next.js dokümanlarında paylaşılan, telefonda ve standart bir dizüstü bilgisayarda görüntülenen bir demo resmi kullandık.
Dizüstü bilgisayar ekranı | Telefon ekranı |
---|---|
Düzen = Doğal: Daha küçük görüntü alanlarında kapsayıcının genişliğine sığacak şekilde küçültülür. Daha büyük bir görüntü alanında resmin doğal boyutunun ötesinde ölçeklendirilmez. Kapsayıcı genişliği %100'dür | |
Düzen = Düzeltildi: Resim duyarlı değil. Genişlik ve yükseklik, oluşturulduğu cihazdan bağımsız olarak "" öğesine benzer şekilde sabitlenir. | |
Düzen = Uyumlu: En boy oranını koruyarak farklı görüntü alanlarında kapsayıcının genişliğine göre ölçeği küçültün veya büyütün. | |
Düzen = Doldur: Genişlik ve yükseklik, üst kapsayıcıyı dolduracak şekilde uzatılır. (Bu örnekte üst öğe <div> genişliği 300*500 olarak ayarlanmıştır)
|
|
Yerleşik geç yükleme sağlayın
Resim bileşeni, varsayılan olarak yerleşik ve performanslı bir geç yükleme çözümü sağlar. <img>
öğesini kullanırken geç yükleme için birkaç seçenek vardır ancak hepsinin kullanımını zorlaştıran dezavantajları vardır. Geliştiriciler aşağıdaki yavaş yükleme yaklaşımlarından birini benimseyebilir:
loading
özelliğini belirtin: Bu özellik tüm modern tarayıcılarda desteklenir.- Intersection Observer API'yi kullanın: Özel bir yavaş yükleme çözümü oluşturmak için çaba, dikkatli bir tasarım ve uygulama gerekir. Geliştiricilerin her zaman buna ayıracak zamanı olmayabilir.
- Görüntüleri gecikmeli yüklemek için üçüncü taraf kitaplığı içe aktarma: Gecikmeli yükleme için uygun bir üçüncü taraf kitaplığını değerlendirmek ve entegre etmek ek çaba gerektirebilir.
Next.js resim bileşeninde, yükleme varsayılan olarak "lazy"
olarak ayarlanır. Geç yükleme, çoğu modern tarayıcıda kullanılabilen Intersection Observer kullanılarak uygulanır. Geliştiricilerin bu özelliği etkinleştirmek için ek bir işlem yapması gerekmez ancak gerektiğinde devre dışı bırakabilirler.
Önemli resimleri önceden yükleme
LCP öğeleri çoğunlukla resimdir ve büyük resimler LCP'yi geciktirebilir. Tarayıcının bu resmi daha erken keşfedebilmesi için kritik resimleri önceden yüklemeniz önerilir. <img>
öğesi kullanıldığında, HTML başlığına aşağıdaki gibi bir ön yükleme ipucu eklenebilir.
<link rel="preload" as="image" href="important.png">
İyi tasarlanmış bir resim bileşeni, kullanılan çerçeveden bağımsız olarak resimlerin yükleme sırasını değiştirmenin bir yolunu sunmalıdır. Next.js resim bileşeni söz konusu olduğunda, geliştiriciler resim bileşeninin priority
özelliğini kullanarak önceden yükleme için iyi bir aday olan resmi belirtebilir.
<Image src="/hero.jpg" alt="hero" height="400" width="200" priority />
priority
özelliği eklemek, işaretlemeyi basitleştirir ve kullanımı daha kolaydır. Görsel bileşen geliştiricileri, belirli ölçütleri karşılayan sayfadaki üst taraftaki görsellerin ön yüklemesini otomatikleştirmek için sezgisel yöntemler uygulama seçeneklerini de keşfedebilir.
Yüksek performanslı resim barındırmayı teşvik edin
Resim optimizasyonunu otomatikleştirmek için resim CDN'leri önerilir. Bu CDN'ler WebP ve AVIF gibi modern resim biçimlerini de destekler. Next.js Resim bileşeni, varsayılan olarak yükleyici mimarisi kullanan bir resim CDN'si kullanır. Aşağıdaki örnekte, yükleyicinin Next.js yapılandırma dosyasında CDN'nin yapılandırılmasına izin verdiği gösterilmektedir.
module.exports = {
images: {
loader: 'imgix',
path: 'https://ImgApp/imgix.net',
},
}
Bu yapılandırmayla geliştiriciler resim kaynağında göreli URL'ler kullanabilir. Çerçeve, mutlak URL'yi oluşturmak için göreli URL'yi CDN yoluyla birleştirir. Imgix, Cloudinary ve Akamai gibi popüler resim CDN'leri desteklenir. Mimari, uygulama için özel bir loader
işlevi uygulayarak özel bulut sağlayıcının kullanımını destekler.
Kendi bünyesinde barındırılan resimleri destekleme
Web sitelerinin resim CDN'lerini kullanamadığı durumlar olabilir. Bu gibi durumlarda, bir resim bileşeni kendi bünyesinde barındırılan resimleri desteklemelidir. Next.js Image bileşeni, CDN benzeri bir API sağlayan yerleşik bir resim sunucusu olarak resim optimize edicisi kullanır. Optimizasyon aracı, sunucuya yüklüyse üretim resmi dönüşümleri için Sharp'ı kullanır. Bu kitaplık, kendi resim optimizasyon ardışık düzenini oluşturmak isteyen herkes için iyi bir seçimdir.
Progresif yüklemeyi destekleme
Kademeli yükleme, gerçek resim yüklenirken genellikle önemli ölçüde daha düşük kaliteli bir yer tutucu resim göstererek kullanıcıların ilgisini çekmek için kullanılan bir tekniktir. Algılanan performansı iyileştirir ve kullanıcı deneyimini geliştirir. Ekranın alt kısmındaki resimler veya ekranın üst kısmındaki resimler için geç yükleme ile birlikte kullanılabilir.
Next.js Image bileşeni, placeholder özelliği aracılığıyla resmin aşamalı yüklemesini destekler. Bu, asıl resim yüklenirken düşük kaliteli veya bulanık bir resim göstermek için LQIP (düşük kaliteli resim yer tutucusu) olarak kullanılabilir.
Etki
Tüm bu optimizasyonlar dahil edildiğinde, Next.js resim bileşeninin üretimde başarılı olduğunu gördük ve benzer resim bileşenleri üzerinde diğer teknoloji gruplarıyla da çalışıyoruz.
Leboncoin, eski JavaScript ön uçlarını Next.js'e taşıdığında resim ardışık düzenini de Next.js resim bileşenini kullanacak şekilde yükseltti. <img>
'ten sonraki/resim öğesine taşınan bir sayfada LCP 2,4 saniyeden 1,7 saniyeye düştü. Sayfa için indirilen toplam resim baytı sayısı 663 KB'dan 326 KB'ya düştü (yaklaşık 100 KB'lık gecikmeli yüklenmiş resim baytı dahil).
Alınan Dersler
Next.js uygulaması oluşturan herkes, optimizasyon için Next.js resim bileşeninden yararlanabilir. Ancak başka bir çerçeve veya içerik yönetim sistemi için benzer performans soyutlamaları oluşturmak istiyorsanız bu süreçte öğrendiğimiz ve işinize yarayabilecek birkaç ders aşağıda verilmiştir.
Güvenlik vanaları faydadan çok zarara neden olabilir
Next.js Image bileşeninin erken bir sürümünde, geliştiricilerin boyutlandırma şartını atlamasına ve belirtilmemiş boyutlara sahip resimler kullanmasına olanak tanıyan bir unsized
özelliği sağladık. Bu özelliği, resmin yüksekliğini veya genişliğini önceden bilmenin mümkün olmadığı durumlarda gerekli olacağını düşündük. Ancak kullanıcıların, boyutlandırma şartıyla ilgili sorunlara her durumda çözüm olarak GitHub sorunlarında unsized
özelliğini önerdiğini fark ettik. Bu durumda, kullanıcılar sorunu CLS'yi kötüleştirmeyen yöntemlerle çözebiliyordu. Ardından unsized
özelliğini kullanımdan kaldırdık.
Faydalı zorlukları anlamsız sıkıntılardan ayırma
Resim boyutlandırma şartı, "yararlı sürtünme"ye örnektir. Bileşenin kullanımını kısıtlar ancak bunun karşılığında size çok büyük performans avantajları sunar. Kullanıcılar, potansiyel performans avantajları hakkında net bir fikir sahibi olurlarsa kısıtlamayı kolayca kabul ederler. Bu nedenle, bu dengeyi dokümanda ve bileşenle ilgili diğer yayınlanmış materyallerde açıklamak faydalı olacaktır.
Ancak performanstan ödün vermeden bu tür sorunlar için geçici çözümler bulabilirsiniz. Örneğin, Next.js Image bileşeni geliştirilirken yerel olarak depolanan resimlerin boyutlarını aramanın can sıkıcı olduğuyla ilgili şikayetler aldık. Bir Babel eklentisi kullanarak derleme sırasında yerel resimlerin boyutlarını otomatik olarak alarak bu işlemi kolaylaştıran statik resim içe aktarma işlemleri ekledik.
Kolaylık özellikleri ile performans optimizasyonları arasında denge kurma
Resim bileşeniniz kullanıcılarına "yararlı bir sürtünme" sunmaktan başka bir şey yapmıyorsa geliştiriciler bunu kullanmak istemez. Resim boyutlandırma ve otomatik srcset
değerleri oluşturma gibi performans özelliklerinin en önemli özellikler olduğunu tespit ettik. Otomatik geç yükleme ve yerleşik bulanık yer tutucular gibi geliştiricilere yönelik kolaylık özellikleri de Next.js Resim bileşenine ilgi uyandırdı.
Kullanım oranını artıracak özellikler için bir yol haritası oluşturun
Tüm durumlar için mükemmel şekilde çalışan bir çözüm geliştirmek çok zordur. Kullanıcıların% 75'i için iyi çalışan bir şey tasarlayıp diğer% 25'e "bu bileşen sizin için uygun değil" demek cazip gelebilir.
Uygulamada bu strateji, bileşen tasarımcısı olarak hedeflerinizle çelişiyor. Geliştiricilerin, performans avantajlarından yararlanmak için bileşeninizi benimsemesini istiyorsunuz. Taşıma işlemini gerçekleştiremeyen ve görüşmenin dışında kaldığını hisseden kullanıcılar varsa bunu yapmak zordur. Bu kişiler hayal kırıklığını ifade ederek benimsemeyi etkileyen olumsuz algılara yol açabilir.
Bileşeniniz için uzun vadede tüm makul kullanım alanlarını kapsayan bir yol haritası oluşturmanız önerilir. Ayrıca, bileşenin çözmeyi amaçladığı sorunlarla ilgili beklentileri belirlemek için dokümanda nelerin desteklenmediği ve neden desteklenmediği konusunda net bir şekilde bilgi verilmelidir.
Sonuç
Resim kullanımı ve optimizasyonu karmaşıktır. Geliştiricilerin, mükemmel bir kullanıcı deneyimi sunarken resimlerin performansı ile kalitesi arasında dengeyi bulması gerekir. Bu da resim optimizasyonunu yüksek maliyetli ve yüksek etkili bir girişim haline getirir.
Her uygulamanın her seferinde tekerleği yeniden icat etmesini beklemek yerine, geliştiricilerin, çerçevelerin ve diğer teknoloji gruplarının kendi uygulamalarında referans olarak kullanabileceği bir en iyi uygulamalar şablonu hazırladık. Diğer çerçevelerin resim bileşenlerini desteklerken bu deneyimin gerçekten değerli olduğunu göreceğiz.
Next.js resim bileşeni, Next.js uygulamalarındaki performans sonuçlarını başarıyla iyileştirerek kullanıcı deneyimini geliştirdi. Bu modelin, daha geniş bir ekosistemde iyi sonuç vereceğine inanıyoruz. Bu modeli projelerinde kullanmak isteyen geliştiricilerden haber almak isteriz.