Resim bileşeni, performansla ilgili en iyi uygulamaları kapsar ve resimleri optimize etmek için kullanıma hazır bir çözüm sunar.
Görüntüler, web uygulamalarında performansla ilgili sorunların yaygın bir kaynağıdır ve optimizasyon için önemli bir odak alanıdır. Optimize edilmemiş resimler sayfa boyutunun artmasına neden olur ve 90th yüzdelik dilimde toplam sayfa ağırlığının% 70'inden fazlasını oluşturur. Resimleri optimize etmenin birden fazla yolu olduğundan, varsayılan olarak performans çözümleri içeren akıllı bir "resim bileşeni" gerekir.
Aurora ekibi, Next.js ile birlikte çalışarak böyle bir bileşen oluşturdu. Amaç, web geliştiricilerin daha fazla özelleştirebileceği optimize edilmiş bir resim şablonu oluşturmaktı. Bu bileşen, diğer çerçevelerde, içerik yönetim sistemlerinde (İYS) ve teknoloji yığınlarında görüntü bileşenleri oluşturmak için iyi bir model ve standart olarak hizmet verir. Benzer bir Nuxt.js bileşeni üzerinde işbirliği yaptık ve gelecekteki sürümlerde görüntü optimizasyonu için Angular ile birlikte çalışıyoruz. Bu yayında, Next.js Image bileşenini nasıl tasarladığımız ve bu süreçte öğrendiklerimiz ele alınıyor.

Resim optimizasyonu sorunları ve fırsatları
Görseller yalnızca performansı değil, işletmeyi de etkiler. Bir sayfadaki resim sayısı, web sitelerini ziyaret eden kullanıcıların dönüşümlerini en iyi tahmin eden ikinci faktördü. Kullanıcıların dönüşüm gerçekleştirdiği oturumlarda, dönüşüm gerçekleştirmediği oturumlara kıyasla% 38 daha az resim vardı. Lighthouse, en iyi uygulamalar denetiminin bir parçası olarak görselleri optimize etmek ve web vitals'ı iyileştirmek için birden fazla fırsat listeler. Resimlerin Core Web Vitals'ı ve kullanıcı deneyimini etkileyebileceği bazı yaygın alanlar şunlardır:
Boyutu belirlenmemiş resimler CLS'yi olumsuz etkiler
Boyutu belirtilmeden sunulan resimler, düzende dengesizliğe neden olabilir ve yüksek bir Cumulative Layout Shift (CLS) değerine katkıda bulunabilir. <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ı doğal en-boy oranına yakın olacak şekilde ayarlanmalıdır. En boy oranındaki büyük bir fark, resmin bozuk görünmesine neden olabilir. CSS'de en boy oranını belirtmenize olanak tanıyan nispeten yeni bir özellik, CLS'yi önlerken resimleri duyarlı bir şekilde boyutlandırmanıza yardımcı olabilir.
Büyük resimler LCP'yi olumsuz etkileyebilir
Bir resmin dosya boyutu ne kadar büyükse indirilmesi o kadar uzun sürer. Büyük bir resim, sayfanın "ana" resmi veya görüntü alanındaki en önemli öğe olabilir. Bu öğe, Largest Contentful Paint'i (LCP) tetiklemekten sorumludur. Önemli içeriğin bir parçası olan ve indirilmesi uzun süren bir resim, LCP'yi geciktirir.
Geliştiriciler, çoğu durumda daha iyi sıkıştırma ve duyarlı resimler kullanarak resim boyutlarını küçültebilir. <img> öğesinin srcset ve sizes özellikleri, farklı boyutlarda resim dosyaları sağlamaya yardımcı olur. Tarayıcı daha sonra ekran boyutuna ve çözünürlüğe bağlı olarak doğru olanı seçebilir.
Kötü görüntü sıkıştırma, LCP'yi olumsuz etkileyebilir
AVIF veya WebP gibi modern resim biçimleri, en çok tercih edilen JPEG ve PNG biçimlerine kıyasla daha iyi sıkıştırma sağlayabilir. Daha iyi sıkıştırma, bazı durumlarda aynı görüntü kalitesi için dosya boyutunu% 25 ila% 50 oranında azaltır. Bu azalma, daha az veri tüketimiyle daha hızlı indirme yapılmasını sağlar. Uygulama, bu biçimleri destekleyen tarayıcılara modern resim biçimlerinde içerik sunmalıdır.
Gereksiz resimlerin yüklenmesi LCP'yi olumsuz etkiler
Sayfa yüklendiğinde, ekranın alt kısmında veya görünüm alanında olmayan resimler kullanıcıya gösterilmez. LCP'ye katkıda bulunmamaları ve LCP'yi geciktirmemeleri için ertelenebilirler. Kullanıcı bu resimlere doğru kaydırdıkça daha sonra yüklemek için geç yükleme kullanılabilir.
Optimizasyonla ilgili zorluklar
Ekipler, daha önce listelenen sorunlar nedeniyle oluşan performans maliyetini değerlendirebilir ve bu sorunların üstesinden gelmek için en iyi uygulama çözümlerini uygulayabilir. Ancak bu durum genellikle pratikte gerçekleşmez ve verimsiz resimler web'i yavaşlatmaya devam eder. Bunun olası nedenleri şunlardır:
- Öncelikler: Web geliştiriciler genellikle kod, JavaScript ve veri optimizasyonuna odaklanır. Bu nedenle, resimlerle ilgili sorunların veya resimleri nasıl optimize edeceklerinin farkında olmayabilirler. Tasarımcılar tarafından oluşturulan veya kullanıcılar tarafından yüklenen resimler, öncelik listesinde üst sıralarda yer almayabilir.
- Hazır çözüm: Geliştiriciler, resim optimizasyonunun ayrıntılarının farkında olsa bile çerçeveleri veya teknoloji yığınları için hazır bir çözümün olmaması caydırıcı olabilir.
- Dinamik resimler: Uygulamanın parçası olan statik resimlerin yanı sıra kullanıcılar tarafından yüklenen veya harici veritabanlarından ya da içerik yönetim sistemlerinden alınan dinamik resimler. Resmin kaynağının dinamik olduğu durumlarda bu tür resimlerin boyutunu tanımlamak zor olabilir.
- İşaretleme aşırı yüklenmesi: Farklı boyutlar için resim boyutunu veya
srcset'ı ekleme çözümleri, her resim için ek işaretleme gerektirir. Bu da sıkıcı olabilir.srcsetözelliği 2014'te kullanıma sunulmuş olsa da bugün web sitelerinin yalnızca%26,5'i tarafından kullanılmaktadır.srcsetkullanılı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ılması gerekir. - 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şlem gerektirir. Geliştiriciler, resimlerin tüm tarayıcılarda sunulabilmesi için içerik anlaşması veya
<picture> öğesi gibi stratejiler kullanmalıdır. - 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 "katlama"dan en iyi mesafeyi de bilemeyebilir. Cihazlardaki farklı görünüm 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ıkça geliştiricilerin her birini değerlendirmesi zor olabilir. Örneğin, Chrome, Fetch Priority özelliğini kaynak denemesi olarak kullanıma sunuyor. Sayfadaki belirli resimlerin önceliğini artırmak için kullanılabilir. Genel olarak, geliştiriciler bu tür geliştirmelerin bileşen düzeyinde değerlendirilip uygulanması durumunda daha kolay bir deneyim yaşayacaktır.
Çözüm olarak resim bileşeni
Resimleri optimize etmek için kullanılabilecek fırsatlar ve bunları her uygulama için ayrı ayrı uygulama zorlukları, bizi bir resim bileşeni fikrine yöneltti. Resim bileşeni, en iyi uygulamaları kapsayabilir ve zorunlu kılabilir. Geliştiriciler, <img> öğesini bir resim bileşeniyle değiştirerek resim performansıyla ilgili sorunlarını daha iyi çözebilir.
Geçtiğimiz yıl boyunca, Next.js çerçevesiyle birlikte çalışarak Image bileşenini tasarlayıp uyguladık. Next.js uygulamalarındaki mevcut <img> öğelerinin yerine aşağıdaki şekilde 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" />
}
Bu 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 görüntü gereksinimlerine göre özelleştirmesine 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 Image bileşenini kullanırken geliştiriciler, düzen kaymalarını önlemek için width ve height özelliklerini kullanarak bir resim boyutu sağlamalıdır. Boyut bilinmiyorsa geliştiriciler, boyutlandırılmış bir kapsayıcının içinde bulunan boyutlandırılmamış bir resmi yayınlamak için layout=fill değerini belirtmelidir. Alternatif olarak, derleme sırasında sabit sürücüdeki gerçek resmin boyutunu almak ve resme eklemek 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ırmadan kullanamadığından tasarım, resim boyutlandırmayı dikkate almalarını ve düzen kaymalarını önlemelerini sağlar.
Duyarlılığı artırma
Geliştiriciler, resimlerin cihazlar arasında duyarlı olmasını sağlamak için <img> öğesinde srcset ve sizes özelliklerini ayarlamalıdır. 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. Bu stilleri, düzen moduna bağlı olarak Image bileşeninin tüm örneklerine uygularız. Üç aşamalı bir çözüm geliştirdik:
deviceSizesözelliği: Bu özellik, uygulama kullanıcı tabanında ortak olan cihazlara göre kesme noktalarını tek seferde yapılandırmak için kullanılabilir. Kesme noktalarının varsayılan değerleri yapılandırma dosyasına dahil edilir.imageSizesözelliği: Bu özellik, cihaz boyutu kesme noktalarına karşılık gelen resim boyutlarını almak için kullanılan, yapılandırılabilir bir özelliktir.- Her resimde
layoutözelliği: Bu özellik, her resim içindeviceSizesveimageSizesözelliklerinin nasıl kullanılacağını belirtmek için kullanılır. Düzen modu için desteklenen değerlerfixed,fill,intrinsicveresponsive'dür.
Duyarlı veya doldurma 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 değerlerini 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 belgelerinde paylaşılan ve telefonda ve standart bir dizüstü bilgisayarda görüntülenen bir demo resmi kullandık.
| Dizüstü bilgisayar ekranı | Telefon ekranı |
|---|---|
| Düzen = İçerik boyutu: Daha küçük görüntü alanlarında kapsayıcının genişliğine sığacak şekilde küçülür. Daha büyük bir görüntü alanında, resmin doğal boyutunun ötesine ölçeklenmez. Kapsayıcı genişliği %100 | |
|
|
| Düzen = Sabit: Resim duyarlı değil. Genişlik ve yükseklik, oluşturulduğu cihazdan bağımsız olarak " |
|
|
|
| Düzen = Duyarlı: En-boy oranını koruyarak farklı görüntü alanlarındaki kapsayıcının genişliğine bağlı olarak ölçeği azaltın veya ölçeği artırın. | |
|
|
Düzen = Doldur: Genişlik ve yükseklik, üst kapsayıcıyı dolduracak şekilde genişletilir. (Bu örnekte üst öğe <div> genişliği 300*500 olarak ayarlanmıştır)
|
|
|
|
Yerleşik geç yükleme özelliği sunma
Resim bileşeni, varsayılan olarak yerleşik ve yüksek performanslı bir geç yükleme çözümü sunar. <img> öğesini kullanırken geç yükleme için birkaç seçenek vardır ancak bunların hepsinin kullanımı zorlaştıran dezavantajları vardır. Geliştiriciler aşağıdaki geç yükleme yaklaşımlarından birini kullanabilir:
loadingözelliğini belirtin: Bu özellik tüm modern tarayıcılarda desteklenir.- Intersection Observer API'yi kullanın: Özel bir geç yükleme çözümü oluşturmak için çaba göstermeniz, dikkatli bir tasarım ve uygulama yapmanız gerekir. Geliştiriciler her zaman buna zaman ayıramayabilir.
- Resimleri geç yüklemek için üçüncü taraf kitaplığı içe aktarma: Geç yükleme için uygun bir üçüncü taraf kitaplığının değerlendirilmesi ve entegre edilmesi ek çaba gerektirebilir.
Next.js Image 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 özelliği devre dışı bırakabilirler.
Önemli resimleri önceden yükleme
LCP öğeleri genellikle resimlerdir ve büyük resimler LCP'yi geciktirebilir. Tarayıcının bu resmi daha erken bulabilmesi için önemli resimleri önceden yüklemeniz iyi bir fikirdir. <img> öğesi kullanılırken HTML başlığına aşağıdaki gibi bir önceden 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ı ayarlama olanağı sunmalıdır. Next.js Image bileşeninde geliştiriciler, resimler bileşeninin priority özelliğini kullanarak önceden yükleme için uygun bir resim 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. Resim bileşeni geliştiricileri, belirli ölçütleri karşılayan sayfadaki ilk bakışta görünen resimlerin önceden yüklenmesini otomatikleştirmek için sezgisel yöntemler uygulama seçeneklerini de inceleyebilir.
Yüksek performanslı resim barındırmayı teşvik etme
Resim optimizasyonunu otomatikleştirmek için resim CDN'leri önerilir. Ayrıca WebP ve AVIF gibi modern resim biçimlerini de desteklerler. Next.js Image bileşeni, yükleyici mimarisi kullanarak varsayılan olarak 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 bir bulut sağlayıcının kullanılmasını destekler.
Kendi bünyesinde barındırılan resimleri destekleme
Web sitelerinin resim CDN'lerini kullanamadığı durumlar olabilir. Bu gibi durumlarda, resim bileşeni kendi kendine 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 edici kullanır. Optimizasyon aracı, sunucuya yüklenmişse üretim resmi dönüşümleri için Sharp'ı kullanır. Bu kitaplık, kendi resim optimizasyonu ardışık düzenini oluşturmak isteyen herkes için iyi bir seçimdir.
Aşamalı yüklemeyi destekleme
Aşamalı yükleme, gerçek resim yüklenirken genellikle çok daha düşük kalitede bir yer tutucu resim göstererek kullanıcıların ilgisini canlı tutmak için kullanılan bir tekniktir. Bu, algılanan performansı artırır ve kullanıcı deneyimini iyileştirir. Bu özellik, sayfanın kaydırma yapmadan görünen kısmının altındaki veya üstündeki resimler için geç yükleme ile birlikte kullanılabilir.
Next.js Image bileşeni, placeholder özelliği aracılığıyla resmin aşamalı olarak yüklenmesini 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 uygulandıktan sonra, üretimde Next.js Image bileşeniyle başarı elde ettik ve benzer görüntü bileşenleri için diğer teknoloji yığınlarıyla da çalışıyoruz.
Leboncoin, eski JavaScript ön ucunu Next.js'ye taşıdığında resim ardışık düzenini de Next.js Image bileşenini kullanacak şekilde yükseltti. <img>'dan sonraki/resim'e taşınan bir sayfada LCP 2,4 saniyeden 1,7 saniyeye düştü. Sayfa için indirilen toplam resim baytı sayısı 663 kB'tan 326 kB'a düştü (yaklaşık 100 kB'lık tembel yüklenen resim baytı ile).
Alınan Dersler
Next.js uygulaması oluşturan herkes optimizasyon için Next.js Image bileşenini kullanabilir. 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 faydalı olabilecek birkaç dersi aşağıda bulabilirsiniz.
Emniyet vanaları faydadan çok zarar verebilir
Next.js Image bileşeninin erken sürümünde, geliştiricilerin boyutlandırma şartını atlamasına ve boyutları belirtilmemiş resimleri kullanmasına olanak tanıyan bir unsized özelliği sunmuştuk. Bunun, resmin yüksekliğinin veya genişliğinin önceden bilinmesinin mümkün olmadığı durumlarda gerekli olacağını düşündük. Ancak, kullanıcıların GitHub sorunlarında unsized özelliğini, CLS'yi kötüleştirmeyen yöntemlerle çözebilecekleri durumlarda bile boyutlandırma şartıyla ilgili sorunlara yönelik genel bir çözüm olarak önerdiğini fark ettik. Daha sonra unsized özelliğinin desteğini sonlandırdık ve bu özelliği kaldırdık.
Faydalı zorlukları gereksiz rahatsızlıklardan ayırın
Bir görüntünün boyutlandırılması gerekliliği, "faydalı sürtünme" örneğidir. Bu, bileşenin kullanımını kısıtlar ancak karşılığında büyük performans avantajları sağlar. Kullanıcılar, olası performans avantajları hakkında net bir fikir sahibi olduklarında kısıtlamayı kolayca kabul eder. Bu nedenle, bu dengeyi bileşenle ilgili dokümanlarda ve yayınlanan diğer materyallerde açıklamak faydalı olur.
Ancak performanstan ödün vermeden bu tür sorunlar için geçici çözümler bulabilirsiniz. Örneğin, Next.js Image bileşeninin geliştirilmesi sırasında, yerel olarak depolanan resimlerin boyutlarını aramanın can sıkıcı olduğu yönünde şikayetler aldık. Bu süreci kolaylaştırmak için statik resim içe aktarma özelliğini ekledik. Bu özellik, Babel eklentisini kullanarak derleme sırasında yerel resimlerin boyutlarını otomatik olarak alır.
Kolaylık özellikleri ile performans optimizasyonları arasında denge kurma
Resim bileşeniniz, kullanıcılarına yalnızca "faydalı sürtünme" uyguluyorsa geliştiriciler bu bileşeni kullanmak istemeyebilir. Resim boyutlandırma ve srcset değerlerinin otomatik olarak oluşturulması 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 Image bileşenine olan ilgiyi artırdı.
Kullanımı artırmak için özelliklerle ilgili bir yol haritası belirleyin
Her durumda mükemmel çalışan bir çözüm oluşturmak çok zordur. Kullanıcıların% 75'i için iyi çalışan bir tasarım yapıp kalan% 25'e "Bu bileşen, bu durumlarda size uygun değil" demek cazip gelebilir.
Bu strateji, bileşen tasarımcısı olarak hedeflerinizle çelişir. Performans avantajlarından yararlanmak için geliştiricilerin bileşeninizi kullanmasını istiyorsunuz. Taşınamayan ve görüşmeye dahil edilmediğini düşünen bir kullanıcı grubu varsa bu durum zorlaşır. Bu kullanıcılar hayal kırıklıklarını dile getirebilir ve bu durum, hizmetin benimsenmesini 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 çözmesi amaçlanan sorunlarla ilgili beklentileri belirlemek için dokümanlarda neyin desteklenmediği ve neden desteklenmediği açıkça belirtilmelidir.
Sonuç
Resim kullanımı ve optimizasyonu karmaşıktır. Geliştiriciler, mükemmel bir kullanıcı deneyimi sağlarken resimlerin performansı ve kalitesi arasında denge kurmalıdır. Bu durum, resim optimizasyonunu yüksek maliyetli ve yüksek etkili bir çaba haline getirir.
Her uygulamanın her seferinde yeniden keşfetmesi yerine, geliştiricilerin, çerçevelerin ve diğer teknoloji yığınlarının kendi uygulamaları için referans olarak kullanabileceği bir en iyi uygulamalar şablonu oluşturduk. Bu deneyim, diğer çerçeveleri desteklerken görüntü bileşenleri konusunda gerçekten değerli olacaktır.
Next.js Image bileşeni, Next.js uygulamalarındaki performans sonuçlarını başarıyla iyileştirerek kullanıcı deneyimini geliştirir. Bu modelin daha geniş ekosistemde iyi sonuç vereceğine inanıyoruz. Projelerinde bu modeli kullanmak isteyen geliştiricilerin görüşlerini almak isteriz.