Çevrimdışı veriler

Sağlam bir çevrimdışı deneyim oluşturmak için PWA'nızın depolama alanı yönetimine ihtiyacı vardır. Önbelleğe alma bölümünde, önbellek depolamanın cihazdaki verileri kaydetmek için bir seçenek olduğunu öğrenmiştiniz. Bu bölümde, veri kalıcılığı, sınırlar ve mevcut araçlar da dahil olmak üzere çevrimdışı verileri nasıl yöneteceğinizi göstereceğiz.

Depolama

Depolama alanı yalnızca dosyalar ve öğelerle ilgili değildir, diğer veri türlerini de içerebilir. PWA'ları destekleyen tüm tarayıcılarda, cihaz üzerinde depolama için aşağıdaki API'ler kullanılabilir:

  • IndexedDB: Yapılandırılmış veriler ve blob'lar (ikili veriler) için NoSQL nesne depolama seçeneği.
  • WebStorage: Yerel depolama veya oturum depolaması kullanılarak anahtar/değer dize çiftlerini depolama yöntemi. Hizmet çalışanı bağlamında kullanılamaz. Bu API eşzamanlı olduğundan karmaşık veri depolama için önerilmez.
  • Önbellek Depolama Alanı: Önbelleğe alma modülünde ele alınmıştır.

Desteklenen platformlarda Depolama Alanı Yöneticisi API'si ile tüm cihaz depolama alanını yönetebilirsiniz. Cache Storage API ve IndexedDB, PWA'lar için kalıcı depolamaya eşzamansız erişim sağlar ve ana iş parçacığı, web çalışanları ve hizmet çalışanlarından erişilebilir. Her ikisi de ağ bağlantısı kesintili olduğunda veya hiç olmadığında PWA'ların güvenilir bir şekilde çalışmasını sağlamada önemli rol oynar. Ancak her birini ne zaman kullanmalısınız?

Ağ kaynakları (ör. HTML, CSS, JavaScript, resimler, videolar ve ses) için Cache Storage API'yi kullanın. Bu kaynaklara URL üzerinden istekte bulunarak erişebilirsiniz.

Yapılandırılmış verileri depolamak için IndexedDB'yi kullanın. Bu, NoSQL benzeri bir şekilde aranabilir veya birleştirilebilir olması gereken verilerin yanı sıra kullanıcıya özel veriler gibi bir URL isteğiyle mutlaka eşleşmeyen diğer verileri de içerir. IndexedDB'nin tam metin araması için tasarlanmadığını unutmayın.

IndexedDB

IndexedDB'yi kullanmak için önce bir veritabanı açın. Bu işlem, veritabanı yoksa yeni bir veritabanı oluşturur. IndexedDB eşzamansız bir API'dir ancak Promise döndürmek yerine geri çağırma alır. Aşağıdaki örnekte, Jake Archibald'ın IndexedDB için küçük bir Promise sarmalayıcısı olan idb kitaplığı kullanılmaktadır. IndexedDB'yi kullanmak için yardımcı kitaplıklar gerekli değildir ancak Promise söz dizimini kullanmak istiyorsanız idb kitaplığını kullanabilirsiniz.

Aşağıdaki örnekte, yemek tariflerini tutmak için bir veritabanı oluşturuluyor.

Veritabanı oluşturma ve açma

Bir veritabanını açmak için:

  1. openDB işlevini kullanarak cookbook adlı yeni bir IndexedDB veritabanı oluşturun. IndexedDB veritabanları sürüm oluşturulduğundan, veritabanı yapısında değişiklik yaptığınızda sürüm numarasını artırmanız gerekir. İkinci parametre, veritabanı sürümüdür. Örnekte 1 olarak ayarlanmıştır.
  2. upgrade() geri çağırması içeren bir başlatma nesnesi openDB()'ye iletilir. Geri çağırma işlevi, veritabanı ilk kez yüklendiğinde veya yeni bir sürüme yükseltildiğinde çağrılır. Bu işlev, işlemlerin gerçekleşebileceği tek yerdir. İşlemler arasında yeni nesne depoları (IndexedDB'nin verileri düzenlemek için kullandığı yapılar) veya dizinler (üzerinde arama yapmak istediğiniz) oluşturma yer alabilir. Veri taşıma işlemi de burada yapılmalıdır. Genellikle, upgrade() işlevi, veritabanının eski sürümüne bağlı olarak her adımın sırayla gerçekleşmesini sağlamak için break ifadeleri olmadan bir switch ifadesi içerir.
import { openDB } from 'idb';

async function createDB() {
  // Using https://github.com/jakearchibald/idb
  const db = await openDB('cookbook', 1, {
    upgrade(db, oldVersion, newVersion, transaction) {
      // Switch over the oldVersion, *without breaks*, to allow the database to be incrementally upgraded.
    switch(oldVersion) {
     case 0:
       // Placeholder to execute when database is created (oldVersion is 0)
     case 1:
       // Create a store of objects
       const store = db.createObjectStore('recipes', {
         // The `id` property of the object will be the key, and be incremented automatically
           autoIncrement: true,
           keyPath: 'id'
       });
       // Create an index called `name` based on the `type` property of objects in the store
       store.createIndex('type', 'type');
     }
   }
  });
}

Örnekte, cookbook veritabanı içinde recipes adlı bir nesne deposu oluşturulur. id özelliği, deponun dizin anahtarı olarak ayarlanır ve type özelliği temel alınarak type adlı başka bir dizin oluşturulur.

Yeni oluşturulan nesne deposuna göz atalım. Tarifleri nesne deposuna ekledikten ve Chromium tabanlı tarayıcılarda Geliştirici Araçları'nı ya da Safari'de Web Inspector'ı açtıktan sonra görmeyi bekleyeceğiniz şey şudur:

IndexedDB içeriklerini gösteren Safari ve Chrome.

Veri ekleme

IndexedDB işlemleri kullanır. İşlemler, eylemleri birlikte gruplandırır. Böylece eylemler tek bir birim olarak gerçekleşir. Veritabanının her zaman tutarlı bir durumda olmasını sağlarlar. Ayrıca, uygulamanızın birden fazla kopyası çalışıyorsa aynı verilere eşzamanlı yazılmasını önlemek için de kritik öneme sahiptirler. Veri eklemek için:

  1. mode değeri readwrite olarak ayarlanmış bir işlem başlatın.
  2. Veri ekleyeceğiniz nesne deposunu alın.
  3. Kaydettiğiniz verilerle add() işlevini çağırın. Yöntem, verileri sözlük biçiminde (anahtar/değer çiftleri olarak) alır ve nesne deposuna ekler. Sözlük, Yapılandırılmış Klonlama kullanılarak klonlanabilir olmalıdır. Mevcut bir nesneyi güncellemek istiyorsanız bunun yerine put() yöntemini çağırırsınız.

İşlemler, işlem başarıyla tamamlandığında çözülen veya işlem hatası ile reddedilen bir done sözü içerir.

IDB kitaplığı belgelerinde açıklandığı gibi, veritabanına yazıyorsanız tx.done, her şeyin veritabanına başarıyla işlendiğini gösteren sinyaldir. Ancak, işlemin başarısız olmasına neden olan hataları görebilmek için tek tek işlemleri beklemeniz faydalı olur.

// Using https://github.com/jakearchibald/idb
async function addData() {
  const cookies = {
      name: "Chocolate chips cookies",
      type: "dessert",
        cook_time_minutes: 25
  };
  const tx = await db.transaction('recipes', 'readwrite');
  const store = tx.objectStore('recipes');
  store.add(cookies);
  await tx.done;
}

Çerezleri eklediğinizde tarif, diğer tariflerle birlikte veritabanında yer alır. Kimlik, indexedDB tarafından otomatik olarak ayarlanır ve artırılır. Bu kodu iki kez çalıştırırsanız iki özdeş çerez girişi elde edersiniz.

Veriler alınıyor

IndexedDB'den nasıl veri alacağınız aşağıda açıklanmıştır:

  1. Bir işlem başlatın ve nesne deposunu ya da depoları, isteğe bağlı olarak da işlem türünü belirtin.
  2. Bu işlemden objectStore() adlı kişiyi arayın. Nesne deposu adını belirttiğinizden emin olun.
  3. Almak istediğiniz anahtarla Call get() işlevini kullanın. Varsayılan olarak, mağaza anahtarını dizin olarak kullanır.
// Using https://github.com/jakearchibald/idb
async function getData() {
  const tx = await db.transaction('recipes', 'readonly')
  const store = tx.objectStore('recipes');
// Because in our case the `id` is the key, we would
// have to know in advance the value of the id to
// retrieve the record
  const value = await store.get([id]);
}

Depolama alanı yöneticisi

PWA'nızın depolama alanını nasıl yöneteceğinizi bilmek, ağ yanıtlarını doğru şekilde depolamak ve yayınlamak için özellikle önemlidir.

Depolama kapasitesi; önbellek depolama, IndexedDB, web depolama ve hatta hizmet çalışanı dosyası ile bağımlılıkları dahil olmak üzere tüm depolama seçenekleri arasında paylaşılır. Ancak kullanılabilir depolama alanı miktarı tarayıcıdan tarayıcıya değişir. Alanınızın tükenmesi olası değildir. Siteler, bazı tarayıcılarda megabaytlar hatta gigabaytlarca veri depolayabilir. Örneğin Chrome, tarayıcının toplam disk alanının% 80'ini kullanmasına izin verir ve tek bir kaynak, tüm disk alanının% 60'ını kullanabilir. Storage API'yi destekleyen tarayıcılarda uygulamanız için ne kadar depolama alanı kaldığını, kotasını ve kullanımını öğrenebilirsiniz. Aşağıdaki örnekte, tahmini kota ve kullanımı almak için Storage API kullanılır. Ardından, kullanılan yüzde ve kalan baytlar hesaplanır. navigator.storage ifadesinin StorageManager örneğini döndürdüğünü unutmayın. Ayrı bir Storage arayüzü vardır ve bu ikisini karıştırmak kolaydır.

if (navigator.storage && navigator.storage.estimate) {
  const quota = await navigator.storage.estimate();
  // quota.usage -> Number of bytes used.
  // quota.quota -> Maximum number of bytes available.
  const percentageUsed = (quota.usage / quota.quota) * 100;
  console.log(`You've used ${percentageUsed}% of the available storage.`);
  const remaining = quota.quota - quota.usage;
  console.log(`You can write up to ${remaining} more bytes.`);
}

Chromium DevTools'da Application (Uygulama) sekmesindeki Storage (Depolama) bölümünü açarak sitenizin kotasını ve kullanılan depolama alanının, kullanan öğelere göre dökümünü görebilirsiniz.

Uygulama bölümündeki Chrome Geliştirici Araçları, Depolamayı Temizle bölümü

Firefox ve Safari, geçerli kaynak için tüm depolama kotasını ve kullanımını görmeye yönelik bir özet ekranı sunmaz.

Veri kalıcılığı

Etkinlik olmadığında veya depolama alanı baskısı olduğunda verilerin otomatik olarak silinmesini önlemek için tarayıcıdan uyumlu platformlarda kalıcı depolama alanı isteyebilirsiniz. İzin verilirse tarayıcı, verileri depolamadan hiçbir zaman çıkarmaz. Bu koruma, hizmet çalışanı kaydını, IndexedDB veritabanlarını ve önbellek depolama alanındaki dosyaları içerir. Kullanıcıların her zaman kontrolü elinde tuttuğunu ve tarayıcı kalıcı depolama alanı izni vermiş olsa bile depolama alanını istedikleri zaman silebileceğini unutmayın.

Kalıcı depolama alanı isteğinde bulunmak için StorageManager.persist() numaralı telefonu arayın. Önceden olduğu gibi, StorageManager arayüzüne navigator.storage mülkü üzerinden erişilir.

async function persistData() {
  if (navigator.storage && navigator.storage.persist) {
    const result = await navigator.storage.persist();
    console.log(`Data persisted: ${result}`);
}

Ayrıca, StorageManager.persisted() işlevini çağırarak mevcut kaynakta kalıcı depolama izninin verilip verilmediğini de kontrol edebilirsiniz. Firefox, kalıcı depolama alanını kullanmak için kullanıcıdan izin ister. Chromium tabanlı tarayıcılar, içeriğin kullanıcı için önemini belirlemek üzere sezgisel bir yöntem kullanarak kalıcılığa izin verir veya kalıcılığı reddeder. Google Chrome'un ölçütlerinden biri örneğin PWA yüklemesidir. Kullanıcı, işletim sistemine PWA için bir simge yüklediyse tarayıcı kalıcı depolama alanı izni verebilir.

Mozilla Firefox, kullanıcıdan depolama alanı kalıcılığı izni istiyor.

API tarayıcı desteği

Web Depolama

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 4.

Source

Dosya Sistemi Erişimi

Browser Support

  • Chrome: 86.
  • Edge: 86.
  • Firefox: 111.
  • Safari: 15.2.

Source

Depolama Yöneticisi

Browser Support

  • Chrome: 55.
  • Edge: 79.
  • Firefox: 57.
  • Safari: 15.2.

Source

Kaynaklar