Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Service Worker ile offline önbellekleme yaparak tekrar ziyaretlerde sayfaların anında nasıl açılmasını sağladığım

nexter

Üye
Katılım
14 Mart 2026
Mesajlar
11
Merhaba arkadaşlar, bugün sizlere kullanıcı deneyimini uçtan uca değiştiren bir optimizasyon hikayesinden bahsedeceğim. Projemizde, kullanıcıların tekrar ziyaretlerinde sayfaların yeniden yüklenmesini beklemekten şikayet ettiğini fark ettik. Özellikle mobilde zayıf ağlarda, her seferinde tüm asset'lerin (CSS, JS, görseller) indirilmesi can sıkıcı bir gecikmeye neden oluyordu. İşte o zaman Service Worker ile offline önbellekleme yapmaya karar verdim ve sonuçlar inanılmazdı!

🔥 Karşılaştığım Temel Sorun

Sorun şuydu: Kullanıcı sitemizi bir kez ziyaret ettiğinde, tarayıcı normal cache kurallarına uysa da, sayfayı tamamen "offline" modda açamıyordu. Sayfa iskeleti (HTML) geliyor ama stil ve scriptler yüklenemeyince beyaz bir ekran veya bozuk bir arayüzle karşılaşılıyordu. Amacım, ilk ziyaretten sonraki tüm ziyaretlerde, sayfanın ağ durumundan bağımsız olarak anında ve tam olarak açılmasını sağlamaktı.

🔧 Service Worker'ı Kayıt Etmek

İlk adım, basit bir JavaScript dosyası ile Service Worker'ı kaydetmek. Bu işlemi ana uygulama JavaScript dosyanızın başında veya HTML'nizin sonunda yapabilirsiniz.

JavaScript:
// app.js veya main.js içinde
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
      console.log('ServiceWorker kaydı başarılı: ', registration.scope);
    }).catch(function(err) {
      console.log('ServiceWorker kaydı başarısız: ', err);
    });
  });
}

Bu kod, tarayıcının Service Worker API'sini destekleyip desteklemediğini kontrol eder ve sayfa yüklendikten sonra '/sw.js' dosyasını kaydeder.

💾 Önbellekleme Stratejisi: Cache First + Network Fallback

Asıl sihir, 'sw.js' dosyasında gerçekleşiyor. Benim tercihim, kritik asset'ler için Cache First, diğer istekler için ise Network First veya Stale-While-Revalidate stratejilerini kullanmak oldu. İşte temel önbellekleme mantığı:

JavaScript:
// sw.js - Service Worker dosyası
const CACHE_NAME = 'site-static-v1';
const ASSETS_TO_CACHE = [
  '/',
  '/index.html',
  '/styles/main.min.css',
  '/scripts/app.bundle.js',
  '/images/logo.svg',
  'https://fonts.googleapis.com/css?family=Roboto'
];

// Kurulum Aşaması: Asset'leri Önbelleğe Al
self.addEventListener('install', event => {
  console.log('[Service Worker] Kurulum');
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('[Service Worker] Kritik dosyalar önbelleğe alınıyor');
        return cache.addAll(ASSETS_TO_CACHE);
      })
      .then(() => self.skipWaiting()) // Yeni SW hemen aktif olur
  );
});

🔄 Fetch Olayını Yakalayıp Cevap Vermek

Service Worker kurulduktan sonra, tüm ağ isteklerini araya girip yönetebilir. Aşağıdaki kod, öncelikle önbellekte (cache) sonucu arar, bulamazsa ağa (network) gider. Ağdan gelen cevabı da bir sonraki kullanım için önbelleğe alır.

JavaScript:
// sw.js devamı
self.addEventListener('fetch', event => {
  console.log('[Service Worker] Fetch ediliyor: ', event.request.url);
  event.respondWith(
    caches.match(event.request)
      .then(cacheResponse => {
        // Önbellekte varsa, onu döndür.
        if (cacheResponse) {
          return cacheResponse;
        }
        // Yoksa, ağ isteği yap.
        return fetch(event.request).then(networkResponse => {
          // Geçerli bir cevap değilse, olduğu gibi döndür.
          if(!networkResponse || networkResponse.status !== 200 || networkResponse.type !== 'basic') {
            return networkResponse;
          }
          // Cevabı klonla (stream sadece bir kez okunabilir)
          const responseToCache = networkResponse.clone();
          caches.open(CACHE_NAME)
            .then(cache => {
              cache.put(event.request, responseToCache);
            });
          return networkResponse;
        });
      }).catch(() => {
        // Hem cache hem network hatası (offline durumu).
        // Örneğin, offline sayfası gösterebilirsiniz.
        // return caches.match('/offline.html');
      })
  );
});

🧹 Eski Cache'leri Temizlemek

Uygulamanızı güncellediğinizde, eski cache'lerin kalmasını istemezsiniz. 'activate' olayında, yeni cache versiyonunuz dışındaki her şeyi silmelisiniz.

JavaScript:
// sw.js devamı
self.addEventListener('activate', event => {
  console.log('[Service Worker] Aktif');
  // Eski cache'leri temizle
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cache => {
          if (cache !== CACHE_NAME) {
            console.log('[Service Worker] Eski cache temizleniyor: ', cache);
            return caches.delete(cache);
          }
        })
      );
    }).then(() => self.clients.claim()) // Kontrolü tüm istemcilere hemen devret
  );
});

Bu yöntemi uyguladıktan sonra, kullanıcıların ikinci ve sonraki ziyaretlerinde sayfaların neredeyse anında açıldığını gözlemledik. Lighthouse performans skorlarında ciddi bir artış oldu, özellikle First Contentful Paint ve Speed Index metrikleri mükemmel seviyelere ulaştı.

Peki siz daha önce Service Worker ile offline deneyimleri geliştirdiniz mi? Cache First stratejisi sizin için sorun yarattı mı, yoksa farklı bir strateji (Network First, Stale-While-Revalidate) mi kullanıyorsunuz? Dinamik içerikli sayfalarda (API istekleri) bu yapıyı nasıl yönettiniz? Yorumlarda deneyimlerinizi paylaşın, tartışalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri