Etkili bir Resim Bileşeni oluşturma

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.

Leena Sohoni
Leena Sohoni
Kara Erickson
Kara Erickson
Alex Castle
Alex Castle

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.

Resimlerin uzantısı olarak resim bileşeni

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:

  1. 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.
  2. 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.
  3. Her resimdeki layout özelliği: Bu özellik, her resim için deviceSizes ve imageSizes özelliklerinin nasıl kullanılacağını belirtmek amacıyla kullanılır. Düzen modu için desteklenen değerler fixed, fill, intrinsic ve responsive'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
Dağlar resmi olduğu gibi gösteriliyor Dağlar resmi küçültüldü
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.
Dağlar resmi olduğu gibi gösterilir Dağlar resmi, olduğu gibi gösterildiğinde ekrana sığmıyor
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.
Ekranı kaplayacak şekilde ölçeklendirilmiş dağ resmi Dağlar resmi, ekrana sığacak şekilde küçültülmüştür.
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)
Dağlar resmi, 300*500 boyutuna sığacak şekilde oluşturuldu Dağlar resmi, 300*500 boyutuna sığacak şekilde oluşturuldu
Farklı düzenler için oluşturulan resimler

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.