İçeriğe geç

Çevrimdışı Uygulama — Metroda Bağlantı Kopunca Ne Gösterilir?

Orta 8 dk Sık karşılaşılır

Önce şunu oku: Tarayıcı Önbelleği — Yeni Sürümü Yayına Aldın, Müşteri Neden Hâlâ Eskisini Görüyor?

30 saniyede özet

Service worker, bağlantı yokken de uygulamanın açılmasını sağlar. Ama her şeyi önbellekten vermek tehlikelidir: değişmeyen iskelet önbellekten gelir, bakiye ağdan istenir, para çevrimdışı gönderilmez.

Metroda tünele girdin, telefonun çekmiyor. Defterine sabah bir harita çizmiştin; ona bakmak hâlâ işe yarar. Ama sabah not ettiğin bakiye, artık yalnızca “sabahki” bakiyedir.

  1. Bayt: Tünelde bankacılık uygulamasını açtım. Hiç açılmadı, tarayıcının dinozoru çıktı.

  2. Sen: Her şeyi önbelleğe alsak? O zaman hep açılır.

  3. Bayt: Açıldı... ama bakiye sabahki. Maaş yatmış, ekranda yok!

  4. Bayt: Haritayı defterden okuyalım. Bakiyeyi ise ancak bağlanınca soralım.

Bağlantı yokken ne olur?

Normalde bir web uygulamasının her dosyası ağdan gelir. Bağlantı koptuğunda, uygulamanın kendisi bile açılmaz.

Bunu çözen şey bir service workerTarayıcıda sayfa ile ağ arasında duran betik. İstekleri yakalar; önbellekten mi ağdan mı cevap verileceğine karar verir.Sözlükte gör →’dır. Sayfa ile ağ arasında durur, her isteği yakalar ve önbellekten mi ağdan mı cevap verileceğine karar verir.

Kafam karıştı, daha basit anlat

Service worker, sayfanın isteklerini yakalayan bir kapı görevlisidir. Ağ yokken de cevap verebilir.

Hızlı kontrolBaşlangıç

Service worker olmayan bir web uygulaması, bağlantı yokken açılmaya çalışılırsa ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Service worker nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Her isteğe kendi kuralı

Service worker her cevabı önbelleğe alıyor ve ağ yokken önbellekten veriyor. Tünelde bakiyene bakıyorsun. Ekranda ne görürsün? Cevabı göster

Sabahki bakiyeyi, şimdiki gibi. Önbellek, kaydedildiği andaki cevabı verir. Arada yatan maaş görünmez ve ekranda bunun eski olduğuna dair hiçbir iz yoktur.

Değişmeyeni defterden oku, parayı tünelden gönderme.
Adım adım oku
  1. Tünele girildi: bağlantı yok.
  2. Sabah çizdiğin harita hâlâ işe yarar.
  3. Sabahki bakiye notu: sabahki, bugünkü değil.
  4. Değişmeyeni defterden oku, parayı tünelden gönderme.

Çözüm, her isteğe türüne göre bir kural vermektir. uygulama iskeletiUygulamanın verisiz hâli: HTML, JS, CSS ve ikonlar. Herkes için aynıdır; çevrimdışı açılış için önbellekte tutulur.Sözlükte gör → herkes için aynıdır; önbellekten gelir. Kampanyalar gibi zararsız içerik de önbellekten gelir, ama yanında “eski olabilir” notuyla.

Bakiye yalnızca ağdan istenir; ağ yoksa “çevrimdışısın” denir. Havale ise çevrimdışı hiç gönderilmez ve bu açıkça söylenir.

Kafam karıştı, daha basit anlat

Değişmeyeni önbellekten ver. Kişisel olanı ağdan iste. Parayı çevrimdışı gönderme.

Hızlı kontrolBaşlangıç

Çevrimdışıyken hangisini önbellekten göstermek en güvenlidir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kampanya listesi önbellekten gösterilecek. Hangisi doğru?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

Metroda bağlantı koptu

Tohum 349321

⚡ Bağlantı yok (metro tüneli)

  1. Uygulamayı aç (HTML, JS, CSS)
  2. Kampanyalara bak
  3. Bakiyeye bak
  4. 500 TL havale gönder

✕ müşteriyi yanıltan sonuç: 0

Hız
Adım 0

Şu an ne oldu?

Service worker yok

Bağlantı yok. Okuyucu uygulamayı açıyor, kampanyalara ve bakiyesine bakıyor, bir havale deniyor.

Görevler0/3

  • Uygulama çevrimdışıyken hiç açılmasınaçık

    İpucu

    Service worker olmasın.

  • Eski bakiye güncelmiş gibi görünsünaçık

    İpucu

    Her şeyi önbellekle.

  • Uygulama açılsın, hiçbir şey olduğundan farklı görünmesinaçık

    İpucu

    İsteğin türüne göre kural.

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. Service worker yok: dört isteğin dördü de tarayıcının hata sayfasına düştü.
  2. “Her şeyi önbellekle” seç. Uygulama açıldı, ama bakiye sabahki ve havale sessizce kuyruğa alındı.
  3. “İsteğin türüne göre kural” seç. Uygulama açıldı; bakiye ve havale için dürüstçe çevrimdışı olunduğu söylendi.
Hızlı kontrolOrta

"Her şeyi önbellekle" kuralı açık. Okuyucu metroda bakiyesine bakıyor. Ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Çevrimdışıyken havale butonuna basıldı. En güvenli davranış hangisi?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Tuzaklar

Sürümü değiştirmeyi unutmak. Yeni sürümü yayınladın ama service worker eski iskeleti vermeye devam ediyor. Önbelleğe sürüm adı ver ve yeni sürümde eskisini sil.

Sessiz kuyruk. Bağlantı gelince kendiliğinden gönderilen bir havale, kullanıcı o arada yeniden denediyse iki kez gidebilir. Tekrar edilebilen her yazma işleminin sunucuda bir idempotencyAynı işlemin bir kez de on kez de çalışsa aynı sonucu vermesi. Dağıtık sistemde timeout aldığında işlemin yapılıp yapılmadığını bilemediğin için zorunludur.Sözlükte gör → anahtarı olmalı.

Ortak cihazda kişisel önbellek. Önbellek, çıkış yapıldıktan sonra da cihazda kalabilir. Kişisel yanıtları önbelleğe yazma; çıkışta önbelleği temizle.

Kafam karıştı, daha basit anlat

Önbelleğe sürüm ver, sessizce para gönderme, kişisel cevabı saklama.

Hızlı kontrolOrta

Uygulamanın yeni sürümü yayınlandı ama bazı kullanıcılar hâlâ eskisini görüyor. En olası neden?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
Derinleş · Mobil bankacılık: isteğin türüne göre çevrimdışı kural 3 dosya · ~70 satır · ilk okumada atlayabilirsin
Proje dosyaları

web/public/ sw.js Service worker: iskelet önbellekten, kampanyalar önbellekten ama işaretli, bakiye ve havale yalnızca ağdan.

web/public/sw.js
const VERSION = 'shell-v42';
const SHELL = ['/', '/app.js', '/app.css', '/icons/logo.svg'];
self.addEventListener('install', (event) => {
event.waitUntil(caches.open(VERSION).then((cache) => cache.addAll(SHELL)));
});
self.addEventListener('activate', (event) => {
// A new version deletes the old shell, so nobody is stuck on it.
event.waitUntil(
caches.keys().then((keys) => Promise.all(keys.filter((k) => k !== VERSION).map((k) => caches.delete(k)))),
);
});
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
// Balances, history and transfers: network only, never cached.
if (url.pathname.startsWith('/api/accounts') || url.pathname.startsWith('/api/transfers')) return;
if (url.pathname.startsWith('/api/campaigns')) {
event.respondWith(networkThenMarkedCache(event.request));
return;
}
event.respondWith(caches.match(event.request).then((hit) => hit ?? fetch(event.request)));
});
async function networkThenMarkedCache(request) {
const cache = await caches.open('campaigns');
try {
const fresh = await fetch(request);
cache.put(request, fresh.clone());
return fresh;
} catch {
const old = await cache.match(request);
if (!old) throw new Error('offline');
// The page reads this header and shows "eski olabilir".
const headers = new Headers(old.headers);
headers.set('X-From-Cache', 'true');
return new Response(old.body, { status: old.status, headers });
}
}

web/src/ main.ts Kayıt: service worker uygulama açılınca kaydediliyor.

web/src/main.ts
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js');
});
}

web/src/pages/ Transfer.tsx Havale: çevrimdışıyken gönderilmiyor, kullanıcıya açıkça söyleniyor.

web/src/pages/Transfer.tsx
import { useState } from 'react';
import { sendTransfer, type TransferForm } from '../api/transfers';
export function TransferButton({ form }: { form: TransferForm }) {
const [message, setMessage] = useState('');
async function send() {
if (!navigator.onLine) {
setMessage('Bağlantı yok, havale gönderilmedi. Bağlanınca yeniden dene.');
return;
}
await sendTransfer(form); // carries an idempotency key
setMessage('Havale gönderildi.');
}
return (
<>
<button type="button" onClick={send}>Gönder</button>
<p role="status">{message}</p>
</>
);
}

Kendini sına

Şimşek turu1/4

Service worker olmadan web uygulaması çevrimdışı açılmaz.

Soru 1/3İleri

Çevrimdışı kuyruğa alınan istek bağlantı gelince gönderilecekse, sunucuda ne olmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 1 Service worker olmayan bir web uygulaması, bağlantı yokken hiç açılmaz. Değişmeyen iskeleti önbellekte tutmak bunu çözer.
  2. 2 Eski veri ancak eski olduğu söylenerek gösterilir. Bakiye gibi kişisel ve parasal veri önbellekten güncel diye verilmez.
  3. 3 Para hareketi çevrimdışı sessizce kuyruğa alınmaz. Kullanıcıya gönderilmediği açıkça söylenir.
Sonraki kapı Kodda yalnızca bir CSS sınıfının adını değiştirdin. Kırk test kırıldı. Bir hafta sonra gerçek bir hata geldi ve hiçbiri kırılmadı. Nasıl? Bileşen Testi — Sınıf Adı Değişti, Test Neden Kırıldı? · 8 dk

4 kart sonraki derste seni bekliyor

0/4 kart bu dersten toplandı