React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?

React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?
React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Bu projeyi uygulamak için temel seviyede React bilgisine ve bir geliştirme ortamına ihtiyacınız var. Çalışmalarınıza başlamadan önce sisteminizde Node.js'in güncel bir sürümünün kurulu olduğundan emin olun.

  • Node.js (LTS sürümü önerilir)
  • React 18 veya üzeri bir sürüm
  • Temel JavaScript (ES6+) bilgisi
  • Bir kod editörü (Visual Studio Code önerilir)

Projenizi oluşturmak için terminalinizde npx create-react-app lazy-load-app komutunu kullanarak temiz bir başlangıç yapabilirsiniz.

Intersection Observer API Nedir?

Intersection Observer API, bir DOM elementinin, hedeflediğimiz başka bir element (genellikle viewport veya bir kapsayıcı) ile ne zaman kesiştiğini asenkron olarak izlememize olanak tanıyan modern bir tarayıcı arayüzüdür. Geleneksel scroll event listener yöntemlerinden farkı, ana iş parçacığını (main thread) yormaması ve çok daha yüksek performans sunmasıdır.

Aşağıdaki tablo, lazy load yöntemlerini karşılaştırmalı olarak göstermektedir:

Yöntem Performans Tarayıcı Desteği Karmaşıklık
Intersection Observer Çok Yüksek Modern Düşük
Scroll Event Listener Düşük Her tarayıcı Yüksek
Native Loading="lazy" Çok Yüksek Modern Çok Düşük

Adım Adım LazyImage Bileşeni Oluşturma

İlk adım olarak, görsellerimizi sarmalayacak ve izleyecek olan LazyImage bileşenini oluşturalım. Bu bileşen, görsel henüz görünür değilken bir placeholder (yer tutucu) gösterecek, görünür olduğunda ise gerçek kaynağı yükleyecektir.

import React, { useState, useEffect, useRef } from 'react';

const LazyImage = ({ src, alt }) => {
  const [isVisible, setIsVisible] = useState(false);
  const imgRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        setIsVisible(true);
        observer.disconnect();
      }
    });

    if (imgRef.current) {
      observer.observe(imgRef.current);
    }

    return () => observer.disconnect();
  }, []);

  return (
    
{isVisible ? (
{alt}
React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?
) : (
Yükleniyor...
)}
); };

Bu kod bloğunda, useRef ile görselin DOM elemanına erişiyoruz. IntersectionObserver, element ekrana girdiği anda isVisible durumunu true yapar ve gözlemciyi kapatır. Bu, gereksiz kaynak tüketimini engellemek için kritik bir adımdır.

Gözlemci Ayarlarını Optimize Etme

Gözlemcinin ne zaman tetikleneceğini belirleyen rootMargin parametresi, lazy loading'in kullanıcı deneyimini iyileştirmek için hayati önem taşır. Örneğin, görsel ekrana girmeden 200 piksel önce yüklenmesini sağlamak, kullanıcının boşluk görmesini engeller.

useEffect(() => {
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      setIsVisible(true);
      observer.disconnect();
    }
  }, {
    rootMargin: '200px 0px',
    threshold: 0.01
  });
  // ... gözlemciyi bağlama işlemleri
}, []);

Buradaki rootMargin değeri, tarayıcının "görünürlük" sınırını genişletir. threshold: 0.01 değeri ise, görselin sadece %1'lik bir kısmı ekrana girdiğinde yükleme işleminin tetiklenmesini sağlar.

Hata Yönetimi ve Güvenli Yükleme

Görsel yükleme sırasında oluşabilecek hataları (örneğin dosya yolunun yanlış olması) yönetmek, uygulamanızın profesyonelliğini artırır. onError event'ini kullanarak hatalı yüklemeleri yakalayabiliriz.

const [hasError, setHasError] = useState(false);

const handleImageError = () => {
  setHasError(true);
};

// Return içinde:
{isVisible && !hasError ? (
  
{alt}
React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?
) : hasError ? (

Görsel yüklenemedi.

) : (
Yükleniyor...
)}

Bu yapı, kullanıcının bozuk bir görsel ikonu görmesini engeller ve hata durumunda kullanıcıya anlamlı bir mesaj gösterilmesini sağlar.

Güvenlik Uyarısı: Kullanıcıdan gelen veya dış kaynaklardan çekilen görsel URL'lerini doğrudan kullanmak XSS (Cross-Site Scripting) riskleri doğurabilir. Görselleri render etmeden önce her zaman güvenilir kaynaklardan geldiğini doğrulayın ve URL'leri sanitize (temizleme) işlemlerinden geçirin.

Performans Testi ve Debug İpuçları

Uygulamanızın doğru çalışıp çalışmadığını test etmek için tarayıcınızın "Network" sekmesini kullanın. Sayfayı yenilediğinizde, ekranda olmayan görsellerin "pending" durumunda kalması veya hiç yüklenmemesi gerekir. Aşağı kaydırdıkça görsellerin ağ trafiğine eklendiğini göreceksiniz.

// Debug için gözlemciyi loglama
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    console.log('Görsel durumu:', entry.isIntersecting);
  });
});

Eğer görseller yüklenmiyorsa, imgRef.current değerinin null olup olmadığını kontrol edin. Genellikle useEffect içindeki ref atamaları, component mount olduktan hemen sonra gerçekleşir.

Sıkça Sorulan Sorular

Intersection Observer ile Native Loading="lazy" arasında fark var mı?

Evet, loading="lazy" tarayıcı tarafından otomatik yönetilir ve çok daha kolaydır. Ancak IntersectionObserver, görsel yüklendiğinde bir animasyon tetiklemek veya özel placeholder'lar kullanmak gibi esnek özelleştirmelere imkan tanır.

Bu yöntem SEO'yu nasıl etkiler?

Google botları artık JavaScript'i çalıştırabildiği için doğru yapılandırılmış bir lazy load yöntemi SEO performansınızı olumlu etkiler. Sayfa hızı arttığı için arama motoru sıralamalarında yükselme şansınız artar.

Çok sayıda görselde performans sorunu yaşanır mı?

Hayır, IntersectionObserver asenkron çalışır ve ana iş parçacığını meşgul etmez. Ancak çok fazla observer nesnesi oluşturmak yerine, tek bir observer ile tüm görselleri yönetmek daha verimlidir.

Mobil cihazlarda "rootMargin" ne olmalı?

Mobil cihazlarda kullanıcılar daha hızlı kaydırma yapabilir. Bu yüzden rootMargin değerini 300px - 500px gibi daha yüksek tutmak, kullanıcı deneyimini iyileştirebilir.

Görsellerin boyutunu nasıl optimize ederim?

Sadece lazy load yeterli değildir. Görselleri WebP veya AVIF formatında sunmak ve srcset kullanarak cihaz ekran boyutuna göre uygun görseli çekmek performansı zirveye taşır.

Responsive Görsel Stratejileri: Srcset ve Sizes Entegrasyonu

Lazy load mekanizmanızı kurduktan sonra, performansın bir sonraki aşaması görsellerin cihaz çözünürlüğüne göre ölçeklenmesidir. Tarayıcıya tek bir görsel yolu vermek yerine, srcset ve sizes özniteliklerini kullanarak bant genişliğinden tasarruf edebilirsiniz. Intersection Observer ile bu yapıyı birleştirmek, düşük çözünürlüklü cihazlarda gereksiz büyük dosyaların yüklenmesini engeller.

const LazyResponsiveImage = ({ src, srcSet, sizes, alt }) => {
  const [isVisible, setIsVisible] = useState(false);
  const imgRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setIsVisible(true);
        observer.disconnect();
      }
    });

    if (imgRef.current) observer.observe(imgRef.current);
    return () => observer.disconnect();
  }, []);

  return (
    
{alt}
React İle Intersection Observer Kullanarak Lazy Load Görsel Yükleme Nasıl Yapılır?
); };

Gelişmiş Performans İzleme: Lighthouse ve Web Vitals

Uygulamanızın lazy load performansını somut verilerle doğrulamak için Google Lighthouse ve Core Web Vitals metriklerini takip etmelisiniz. Özellikle Largest Contentful Paint (LCP) değeri, görsel yükleme stratejinizden doğrudan etkilenir.

LCP İyileştirme İpuçları

  • Above-the-fold (Ekranın üst kısmı) görselleri: Sayfa ilk yüklendiğinde görünen görseller için lazy load kullanmayın. Bu görselleri doğrudan yükleyin ve priority özniteliği ile tarayıcıya öncelik verin.
  • Layout Shift (CLS) Engelleme: Görsel yüklenmeden önce kapsayıcı elemente (container) sabit bir aspect-ratio veya min-height verin. Böylece görsel yüklendiğinde sayfa içeriği aşağı kaymaz.
Metrik Hedef Değer Lazy Load Etkisi
LCP < 2.5s Doğru uygulanırsa iyileşir.
CLS < 0.1 Kapsayıcı boyutları ile kontrol altına alınmalıdır.

Alternatif Yaklaşım: Kütüphane Kullanımı

Eğer projenizde çok karmaşık görsel senaryoları (blur-up efektleri, watermark, gelişmiş hata yönetimi) varsa, tekerleği yeniden icat etmek yerine sektör standardı olan kütüphaneleri tercih edebilirsiniz. react-lazy-load-image-component gibi kütüphaneler, Intersection Observer'ı arka planda yöneterek size hazır bileşenler sunar.

Bu kütüphanelerin sağladığı avantajlar şunlardır:

  1. Cross-browser uyumluluğu: Eski tarayıcılar için otomatik fallback desteği.
  2. Blur-up efekti: Düşük çözünürlüklü bir görselin bulanık halini önizleme olarak gösterme.
  3. Debounce desteği: Hızlı kaydırma işlemlerinde gereksiz tetiklemeleri engelleme.
İpucu: Küçük ve orta ölçekli projelerde kendi Intersection Observer kancanızı (hook) yazmak bundle boyutunuzu küçültürken, büyük ölçekli ve ekip bazlı projelerde kütüphane kullanımı bakım kolaylığı sağlar.

Sonuç

React uygulamalarında IntersectionObserver kullanarak lazy load görsel yükleme, hem kullanıcı deneyimini hem de teknik performans metriklerini iyileştiren vazgeçilmez bir tekniktir. Bu rehberde öğrendiğiniz temel yapıyı, projenizin ihtiyaçlarına göre özelleştirerek daha karmaşık görsel galerileri veya sonsuz kaydırma (infinite scroll) özellikli sayfalar oluşturabilirsiniz.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce gerekli güvenlik testlerini yapmalı ve modern kütüphanelerin (örneğin react-lazy-load-image-component) sunduğu ek özellikleri değerlendirmelisiniz.

Bir sonraki adım olarak, görselleriniz için srcset kullanımını araştırarak farklı ekran çözünürlükleri için responsive görsel stratejileri geliştirebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Mert Çelik

Teknoloji dünyasını ve dijital araçları günlük hayata entegre etme konusunda içerikler üretiyorum. Karmaşık teknik rehberleri en yalın haliyle sunmayı hedefliyorum.

Yorumlar (0)

Yorum Yaz