Lazy Loading vs Eager Loading

Lazy Loading vs Eager Loading

Bir object relational mapping ile çalışırken veri getirme/yükleme iki tipte sınıflandırılabilir: Lazy ve eager. Eager loading, web sayfasının tüm içeriğini mümkün olan en kısa sürede oluştururken, lazy loading gerekli olmayan içeriğin görüntülenmesini geciktirir.
Elif Koç16 Ağu 2023

Göz alıcı bir web sitesi harikadır, ancak bir sitenin kullanıcı çekebilmesi için bu yetmez. Çeşitli araştırmalar, internet kullanıcılarının yaklaşık yüzde ellisinin bir web sayfasının iki saniye veya daha kısa sürede yüklenmesini beklediğini gösteriyor. Yani sitenin yüklenmesinin üç saniye veya daha uzun sürmesi ziyaretçi kaybetme şansını oldukça yükseltmekte. Bu sebeple, geliştirme yaparken bazı konulara hakim olmak oldukça önemlidir.


 .NET 4.0 ve Entity Framework ile veri nesnelerini yükleyebileceğimiz farklı yöntemler bulunmaktadır. Bunlardan bazıları:

  • Eager loading veya Include ile ‘Query Path’ tanımlama
  • Lazy loading
  • Explicit loading


Eager loading’in belirli bir miktarda metin ve az sayıda resim/video içeren daha basit sayfalarda kullanılması gerekirken, lazy loading daha fazla içeriğe sahip büyük dosyaların olduğu sayfalar için kullanılmalıdır.


Önce lazy loading’i detaylarıyla inceleyelim.


Lazy loading

Performansı artırmak ve sistem kaynaklarını kurtarmak için ihtiyaç duyulana kadar kaynakların veya nesnelerin yüklenmesini veya başlatılmasını geciktirme uygulamasıdır. Örneğin, kullanıcı bir web sayfasındaki görselin bulunduğu yere imleç ile geldiğinde lazy loading ile görsel yüklenebilir.


 

Lazy loading Görsel kaynağı


Lazy loading’in avantajları aşağıdaki gibi sıralanabilir:

  • İlk yüklenme süresini azaltır: Bir web sayfasını lazy loading ile görüntülemek, sayfanın daha hızlı yüklenmesini sağlar.
  • Bant genişliğinin korunması: Lazy loading, içeriği yalnızca istendiğinde kullanıcılara sunarak bant genişliğini korur. Bant genişliği, internet ile bağlantılı olan bir cihazın, bir zaman dilimi içerisinde maksimum veriyi iletip taşımasıdır.
  • Sistem kaynaklarının korunması: Lazy loading, hem sunucu hem de istemci kaynaklarını korur, çünkü yalnızca gerekli görüntüler ve kodların oluşturulması veya yürütülmesi gerekir.


Lazy loading ne zaman kullanılmalıdır?

  • Lazy loading, web sayfasının ilk yüklenmesinde kullanıcı deneyimi için çok önemli olmayan, çok sayıda ağır içeriğe (görüntüler, gifler ve videolar gibi) sahip uzun web sayfaları için harikadır.
  • Hangi sayfalar için lazy loading kullanılacağına dair katı kurallar yoktur. Hangi sayfada kullanılacağını sitenin performans ve etkileşim durumları karşılaştırılarak karar verilebilir.
  • Sayfanın daha hızlı yüklenmesi istendiğinde lazy loading kullanılabilir. Sayfanın hızlı yüklenmesi ziyaretçi deneyimini iyileştirir, ilgili ziyaretçi ve dönüşüm sayısını artırır ve SEO’ya yardımcı olur.
  • Veri kullanım maliyetinden tasarruf sağlamak isteniyorsa lazy loading kullanılması avantaj sağlar. Tarayıcı, ziyaret başına toplam sayfa içeriğinin bir kısmını yüklediği için veri kullanımını azaltır. Bu hem admin hem de ziyaretçiler için veri maliyetlerinden tasarruf sağlar. 


Lazy loading ve Entity Framework kullanımı için kurallar şu şekilde sıralanabilir

  • context.Configuration.ProxyCreationEnabled ‘true’ olarak atanmalıdır.
  • context.Configuration.LazyLoadingEnabled ‘true’ olarak atanmalıdır.
  • Navigasyon özelliği (navigation property), public veya virtual olarak atanmalıdır. Navigasyon özelliği virtual olarak atandıysa, context yükleme yapmaz. 


Navigation Property:Navigasyon özelliği, bir ilişkilendirmenin bir ucundan diğer ucuna gezinmeye izin veren bir Entity türü üzerindeki isteğe bağlı bir özelliktir. Başka bir ifade ile veritabanında bir foreign key ilişkisini temsil etmenin veya iki entity arasındaki ilişkiyi tanımlamanın bir yoludur. Diğer özelliklerden farklı olarak, gezinme özellikleri veri taşımaz.


Context:Entity Framework kullanırken, System.Data.Entity sınıfında yer alan DbContext sınıfından kalıtım alınır. Veritabanı işlemlerini yapan sınıf oluşturulmuş olur. Context sınıfının işlevleri aşağıdaki görselde görülebilir. 


 

Context


Lazy loading’i uygulamak için kullanılabilecek birkaç açık kaynak kitaplığı vardır: blazy.js ve LazyLoadblazy.js; görüntüleri, iframe’leri, videoları ve diğer kaynakları lazy loading ile yüklemek ve çoklu hizmet sunmak için kullanılan bir Javascript kitaplığıdır. LazyLoad; görüntüleri, kullanıcının görüntü alanına girmesiyle otomatik olarak yükleyen bir komut dosyasıdır.


Kodumuzda bulunan lazy loading metodları temel başlatma, sanal proxy, ghost ve value holder kavramlarını içerir:

  • Tembel başlatma (lazy initialization): Bir nesnenin tembel başlatılması, nesnenin yaratılmasının ilk kullanımına kadar ertelendiği anlamına gelir. Performansı artırmak, gereksiz hesaplamaları önlemek ve program belleği gereksinimlerini azaltmak için kullanılır. 
  • Sanal proxy (virtual proxy): Bir nesneye erişirken, gerçek nesneyle aynı interface’e sahip sanal bir nesne çağrılır. Sanal nesne çağrıldığında, gerçek nesne yüklenir.
  • Ghost: Bir nesne yalnızca bir tanımlayıcı kullanılarak kısmi olarak yüklenir. Nesnedeki bir özellik ilk kez çağrıldığında, tüm veriler yüklenir.
  • Value holder: Lazy loading davranışını işleyen genel bir nesne oluşturulur. Bu nesne, bir nesnenin veri alanları yerine görünmelidir. 


 

Lazy loading


Lazy loading durumunda, ilgili nesneler (alt nesneler) talep edilene kadar üst nesnesiyle birlikte otomatik olarak yüklenmez. Varsayılan olarak LINQ, lazy loading’i destekler.


 

Lazy loading özeeliğinin kapatılması

 

Yukarıdaki görselde lazy loading özelliğinin kapatılması gösterilmiştir. Artık alt nesneleri üst nesneyle tek sorguda getirebiliriz.

Şimdi ise lazy loading ve CDN (Content Delivery Network, İçerik Dağıtım Ağları)) kavramlarının ilişkisini inceleyelim. Lazy loading ve CDN, sayfa yükleme süresini iyileştirmenin ve son kullanıcı deneyimini optimize etmenin iki yoludur. CDN, kaynakları cache server’a yerleştirerek kullanıcıya kaynaklara daha hızlı erişim konusunda yardımcı olur. Lazy loading ile CDN’yi web sitesi performans optimizasyonu için karşılaştırırsak;

  • Lazy loading, gereksiz kaynak indirmeyi ve kod yürütmeyi engeller. Ancak, kullanıcı gerçekten büyük veya çok sayıda kaynak talep ettiğinde (request) yardımcı olamaz, yani performans açısından kolaylık sağlayamaz.
  • CDN, kaynakları ön belleğe alır ve bunları kullanıcılara  çok daha hızlı sunabilir. Ancak lazy loading’in aksine kullanıcıların gerçekten ihtiyaç duymadığı gereksiz kaynakları da kullanıcıya iletebilir.
  • En uygun çözüm, her iki tekniğin birleştirilmesidir. Bir CDN aracılığıyla kaynakları sunarken, lazy loading ile kullanıcıların yalnızca ihtiyaç duyduğu kaynakların indirilmesi ve kullanıcının gerçekten ilgili kaynağa ihtiyaç duyması halinde, bunun önbelleğe alınması ve hızlı bir şekilde teslim edilmesi sağlanabilir.


 

Lazy loading (görsel kaynağı)


Görüntülenmeyen içerik için, gerçek görüntülerin yerini tutacak yer tutucu (placeholder) görüntüler yüklenir. Bu yer tutucuların yüklenmesi, tam olarak oluşturulmuş içeriğe göre çok daha az zaman alır. Gerçek görüntüler, yer tutucuları görüntülendikten sonra (ekranda aşağı doğru kaydırıldığında) hızla yüklenir. Lazy loading yaygın olarak görsellerde kullanılsa da metin, video veya diğer gömülü içerik dahil olmak üzere herhangi bir sayfa öğesine de uygulanabilir.


 

Placeholder image (görsel kaynağı)


Özetle, lazy loading web sayfaları tarafından yükleme süresini optimize etmek için kullanılan bir tekniktir. Lazy loading ile bir web sayfası ilk başta yalnızca geçerli içeriği yükler ve kullanıcı ihtiyaç duyana kadar sayfa içeriğini yüklemek için bekler. Lazy loading, bir web sayfasının açılması için geçen süreyi azaltır, çünkü tarayıcı aynı anda sayfadaki içeriğin yalnızca bir kısmını yükler. Sürece “lazy” denir çünkü yüklemeyi ihtiyaç duyulana kadar geciktirir.  Yukarıdaki gif’te olduğu gibi arama motorunda görsel aradığımızı düşünelim. Arama motoru tek bir sonuç sayfasında birçok görsel bulur. Bu görsellerin hepsini aynı anda sayfaya yüklemek mantıklı olmaz, çünkü hepsinin yüklenmesine gerek kalmadan aranılan görsele ulaşılabilir. Neden asla görmeyeceğimiz görseller için zaman ve veri harcayalım? Arama motorlarındaki görsel içerik arama kısımları bu sebeple lazy loading yöntemini uygular. 

Eager loading

Eager loading, parent entity için olan bir sorgunun, child entity için ayrı bir sorguya gerek duyulmaksızın, sorgunun bir parçası olarak ilgili child entity’leri de yüklediği işlemdir. İlk yükleme süresinin uzun olması ve çok fazla gereksiz verinin yüklenmesi performansı olumsuz etkileyebilir. Eager loading, ihtiyaç duyulan tüm varlıkları (entities) tek seferde yüklemek gerektiğinde kullanılmalıdır. Bunun anlamı, tüm varlıkların tek bir veritabanı çağrısında yüklenmesidir. 


Eager loading’i, lazy loading’in tersi gibi düşünülebilir. Eager loading ile bir web sayfası tüm içeriğini anında yükler. Eager loading, tarayıcının web sayfasının tüm içeriğini ön belleğinde saklamasına olanak tanır. Bu, ziyaretçilerin sayfaya yeniden dönmesi durumunda yardımcı olabilir. Ancak, bu yöntem daha büyük web sayfası dosyalarını yüklemek için yavaş olabilir. Üzerinde daha az veri bulunan sayfalar, eager loading yapma eğilimindedir. Örneğin genellikle Wikipedia sayfalarına görsellere kıyasla daha az alan kaplayan metinler hakimdir. Bu nedenle Wikipedia, sayfa içeriği için lazy loading yerine eager loading yöntemini seçer.

Eager loading ve LINQ sorgusu

Yukarıdaki görselde eager loading örneğinde, Kategoriler ve Kategoriler ile ilişkili Urunler için veritabanını yalnızca bir kez çağırmak amacıyla kullandığımız LINQ sorgusu görülebilmektedir. Eager loading durumunda child nesneler, parent nesnesiyle birlikte otomatik yüklenir. Eager loading kullanmak için Include() metodunun kullanılması gerekir. 

Lazy loading ile eager loading’i farkları

  • Lazy loading bir kaynağın başlatılmasını geciktirirken, eager loading kod yürütülür yürütülmez kaynağı başlatır veya yükler.
  • Eager loading, bir kaynak tarafından başvurulan ilgili varlıkların önceden yüklenmesini de içerir. Örneğin, include ifadesine sahip bir PHP scriptinde eager loading gerçekleşir. Kod yürütülür yürütülmez eager loading, dahil edilen kaynakları çeker ve yükler. 
  • Eager loading, kaynakları arka planda yüklemek için bir fırsat veya ihtiyaç olduğunda faydalıdır. Örneğin bazı websiteleri “yükleniyor” ifadesini gösterir ve web uygulamasının çalışması için gereken tüm kaynakları yükler.


 HTML’in ‘loading’ özelliğinin kullanılması
“loading” özniteliği ile bir web sayfasındaki her bir görselin yükleme prosedürleri üzerinde değişiklik yapabiliriz. Bir öğesinin loading ayarını belirtmek için aşağıdaki görseldeki gibi loading özniteliğine atama yaparız.


 

HTML ve loading özeelliği


Lazy loading, sayfa performansını artırmak ve ziyaretçileri sitemizde tutmak için harika bir seçenektir. Lazy loading seçilirse, site başlatılmadan önce test edilmelidir. Herhangi bir hata gizli içeriğin gösterilmesini engelleyebilir. Hiçbir içeriğin görülememesi, içeriğin yavaş yüklenmesinden daha kötüdür.


Hibernate üzerinde lazy ve eager loading

Hibernate, Java geliştiricilerin kullandığı bir object relational map kütüphanesidir. Entitiy’ler arasında parent-child ilişkisi sağlar. Bir parent kaydın birden fazla child kaydı olabileceği durum olabilir. Varsayılan olarak, Hibernate kullanımında bir parent kayıt getirildiğinde tüm child kayıtlar da getirilir. Bu Java’da hibernate kullanımında eager loading olarak bilinir. 


 

Eager loading ve Hibernate


Bir parent’in birden fazla çocuk kaydına sahip olduğu bir durumu ele alalım. Bu durumda, hibernate tüm child kayıtları isteğe bağlı olarak yani erişim talebi geldiğinde otomatik olarak yükler. Amaç performansı artırmaktır. Varsayılan olarak lazy=”false” şeklinde atanır ve tüm child kayıtlar, parent ile yüklenir. Lazy loading’i kullanabilmek için lazy=”true” ifadesi kullanılabilir.


 

Lazy loading ve Hibernate


Lazy loading ve Entity Framework birlikte kullanılırken, context öncelikle entity verilerini veritabanından yükler. Ardından OgrenciAdresi özelliğine eriştiğimizde OgrenciAdresi entity'sini yükler.


 

Lazy loading ve Entity Framework


 

Lazy loading özelliğinin Entity Framework ile kullanımında geçersiz kılınması


Bu yazımızda internet sitelerinin yüklenmesi için uygulanan yöntemler olan lazy loading ve eager loading kavramlarına değindik. Performansı artırmak ve sistem kaynaklarını kurtarmak için ihtiyaç duyulana kadar kaynakların/nesnelerin yüklenmesini geciktirmek istediğimizde lazy loading, web sitesindeki tüm kaynakları tek seferde yüklemek istediğimizde ise eager loading yöntemlerine başvurulmaktadır.


Kaynaklar

Wikipedia, Lazy loading

Microsoft, Eager loading of related data

webpack, Lazy loading

Gumlet, Guide on lazy load images

Kumar S., React Progressive Graceful Image with Lazy-Loading — All-in-one ReactJS npm package for Image Loading, Medium


 

Miuul topluluğunun bir parçası ol!

Abone ol butonuna tıklayarak Miuul'dan pazarlama ve haber içerikleri almayı onaylıyorum.