Çevrimdışı veriler

Güçlü bir çevrimdışı deneyim oluşturmak için PWA'nızın depolama alanı yönetimini sağlaması gerekir. Önbelleğe alma bölümünde, önbellek depolamanın bir cihaza veri kaydetmek için kullanabileceğiniz seçeneklerden biri olduğunu öğrenmiştiniz. Bu bölümde veri kalıcılığı, sınırlar ve kullanılabilir araçlar dahil çevrimdışı verileri nasıl yöneteceğinizi göstereceğiz.

Depolama

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

  • IndexedDB: Yapılandırılmış veriler ve blob'lar (ikili veri) için bir NoSQL nesne depolama seçeneği.
  • WebStorage: Yerel depolama veya oturum depolaması kullanarak anahtar/değer dizesi çiftlerini depolamanın bir yolu. Service Worker bağlamında kullanılamaz. Bu API eşzamanlı olduğundan karmaşık veri depolama işlemlerinde kullanılması önerilmez.
  • Önbellek Depolama Alanı: Önbelleğe alma modülünde açıklandığı şekilde.

Desteklenen platformlarda Storage Manager API'sini kullanarak cihazın depolama alanının tamamını yönetebilirsiniz. Cache Storage API ve IndexedDB, PWA'lar (Progresif Web Uygulaması) için kalıcı depolama alanına eşzamansız erişim sağlar. Bu API'lere ana iş parçacığı, web çalışanları ve hizmet çalışanlarından erişilebilir. Ağ stabil olmadığında veya olmadığında PWA'ların güvenilir şekilde çalışmasında her ikisi de temel rol oynar. Peki bu iki türü ne zaman kullanmalısınız?

Ağ kaynakları ve HTML, CSS, JavaScript, resimler, videolar ve ses gibi bir URL aracılığıyla isteyerek erişeceğiniz şeyler için Cache Storage API'sini kullanın.

Yapılandırılmış verileri depolamak için IndexedDB'yi kullanın. Buna NoSQL gibi aranabilir veya birleştirilebilir olması gereken veriler ya da bir URL isteğiyle eşleşmek zorunda olmayan kullanıcıya özel veriler gibi diğer veriler de dahildir. IndexedDB'nin tam metin araması için tasarlanmadığını unutmayın.

IndexedDB

IndexedDB'yi kullanmak için önce bir veritabanı açın. Mevcut bir veritabanı yoksa yeni bir veritabanı oluşturulur. IndexedDB, eşzamansız bir API'dir ancak Promise döndürmek yerine geri çağırma yapar. Aşağıdaki örnekte, IndexedDB için küçük bir Promise sarmalayıcı olan Jake Archibald'ın idb kitaplığı kullanılmaktadır. IndexedDB'yi kullanmak için yardımcı kitaplıklara gerek yoktur ancak Promise söz dizimini kullanmak istiyorsanız idb kitaplığı bir seçenektir.

Aşağıdaki örnek, pişirme tariflerini saklayacak bir veritabanı oluşturur.

Veritabanı oluşturma ve açma

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

  1. cookbook adında yeni bir IndexedDB veritabanı oluşturmak için openDB işlevini kullanın. IndexedDB veritabanlarının sürümü olduğundan, veritabanı yapısında her 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ğırma içeren bir başlatma nesnesi, openDB() yöntemine geçirilir. 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ştirilebileceği tek yerdir. İşlemler, yeni nesne depoları (IndexedDB'nin verileri düzenlemek için kullandığı yapılar) veya dizinler (arama yapmak istediğiniz) oluşturmayı içerebilir. Veri taşıma işlemi de tam olarak bu noktada gerçekleşmelidir. Genellikle upgrade() işlevi, her bir adımın veritabanının eski sürümüne bağlı olarak sırayla gerçekleşmesini sağlamak üzere break ifadesi içermeyen 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');
     }
   }
  });
}

Bu örnek, cookbook veritabanının içinde recipes adlı bir nesne deposu oluşturur. id özelliği, mağazanın dizin anahtarı olarak ayarlanır ve type özelliğini temel alarak type adında başka bir dizin oluşturur.

Şimdi, az önce oluşturulan nesne deposuna bir göz atalım. Nesne deposuna tarif ekledikten ve Chromium tabanlı tarayıcılarda Geliştirici Araçları'nı veya Safari'de Web Denetleyicisi'ni açtıktan sonra şunları görebilirsiniz:

Safari ve Chrome, IndexedDB içeriklerini gösteriyor.

Veri ekleme

IndexedDB, işlemleri kullanır. İşlemler, işlemleri bir arada gruplandırdığından işlemler bir birim olarak gerçekleşir. Veritabanının her zaman tutarlı bir durumda olmasını sağlar. Ayrıca, uygulamanızın birden fazla kopyası çalışıyorsa aynı verilere eş zamanlı olarak yazılmasını önlemek açısından önemlidir. Veri eklemek için:

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

İşlemler, işlem başarıyla tamamlandığında veya bir işlem hatası ile reddedildiğinde done ödeme taahhüdü verir.

IDB kitaplığı dokümanlarında açıklandığı gibi, veritabanına yazıyorsanız tx.done, her şeyin veritabanına başarıyla kaydedildiğinin işaretidir. Ancak işlemin başarısız olmasına neden olan hataları görebilmek için her işlemi ayrı ayrı beklemenizde fayda vardır.

// 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 ekledikten sonra, tarif diğer tariflerle birlikte veritabanında yer alır. Kimlik otomatik olarak ayarlanır ve indexDB tarafından otomatik olarak artırılır. Bu kodu iki kez çalıştırırsanız, özdeş iki çerez girişiniz olur.

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 veya depoları ve isteğe bağlı olarak işlem türünü belirtin.
  2. Bu işlemde objectStore() adlı kişiyi ara. Nesne deposu adını belirttiğinizden emin olun.
  3. Almak istediğiniz anahtarla get() numaralı telefonu arayı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 akışla almak için özellikle önemlidir.

Depolama kapasitesi; Önbellek Depolama, IndexedDB, Web Depolama, hatta Service Worker dosyası ve bağımlılıkları dahil tüm depolama seçenekleri arasında paylaşılır. Ancak, kullanılabilir depolama alanı tarayıcıdan tarayıcıya değişiklik gösterir. Büyük ihtimalle tükenmeyeceksiniz. Siteler, bazı tarayıcılarda megabaytlar, hatta gigabaytlarca veri depolayabilir. Örneğin Chrome, tarayıcının toplam disk alanının% 80'ine kadar, tek bir kaynak ise tüm disk alanının% 60'ına kadarını kullanmasına izin verir. Storage API'yi destekleyen tarayıcılarda uygulamanızın hâlâ ne kadar depolama alanı kaldığını, kotasını ve kullanımını öğrenebilirsiniz. Aşağıdaki örnekte, tahmini kota ve kullanımı öğrenmek için Storage API kullanılmış, ardından kullanılan yüzde ve kalan bayt sayısı hesaplanmıştır. navigator.storage işlevinin StorageManager örneği döndürdüğünü unutmayın. Ayrı bir Storage arayüzü vardır ve kullanıcıların kafasını 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 Geliştirici Araçları'nda, Uygulama sekmesindeki Depolama bölümünü açarak sitenizin kotasını ve kullanılan depolama alanı miktarını, bu miktarı kullananlara göre ayrılmış şekilde görebilirsiniz.

Uygulama'da Chrome Geliştirici Araçları, Depolama Alanını Temizle bölümü

Firefox ve Safari, geçerli kaynağa ilişkin tüm depolama alanı kotasını ve kullanımını görmek için bir özet ekranı sunmaz.

Veri kalıcılığı

Etkinlik olmadığında veya depolama alanı baskısı olduğunda verilerin otomatik olarak çıkarılmasını önlemek için tarayıcıdan uyumlu platformlarda kalıcı depolama alanı talep edebilirsiniz. İzin verilirse tarayıcı, verileri hiçbir zaman depolama alanından çıkarmaz. Bu koruma; hizmet çalışanı kaydı, IndexedDB veritabanlarını ve önbellek depolama alanındaki dosyaları içerir. Tarayıcının kalıcı depolama alanı sağlaması durumunda bile kullanıcıların her zaman sorumlu olduğunu ve istedikleri zaman depolama alanını silebileceğini unutmayın.

Kalıcı depolama alanı isteğinde bulunmak için StorageManager.persist() numaralı telefonu arayın. Daha önce olduğu gibi, StorageManager arayüzüne navigator.storage mülkü üzerinden erişim sağlanır.

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

StorageManager.persisted() numaralı telefonu arayarak mevcut kaynakta kalıcı depolama alanı 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 yaklaşıma göre kalıcılık verir veya reddeder. Google Chrome için kriterlerden biri, örneğin PWA yüklemesidir. Kullanıcı, işletim sistemine PWA için bir simge yüklediyse tarayıcı, kalıcı depolama alanı sağlayabilir.

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

API Tarayıcısı desteği

Web Depolama

Tarayıcı Desteği

  • 4
  • 12
  • 3,5
  • 4

Kaynak

Dosya Sistemi Erişimi

Tarayıcı Desteği

  • 86
  • 86
  • 111
  • 15,2

Kaynak

Depolama Yöneticisi

Tarayıcı Desteği

  • 55
  • 79
  • 57
  • 15,2

Kaynak

Kaynaklar