Çevrimdışı veriler

Güçlü 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, bir cihaza veri kaydetmek için kullanabileceğiniz seçeneklerden biri olduğunu öğrendiniz. Bu bölümde veri kalıcılığı, sınırlar ve kullanılabilir araçlar dahil olmak üzere çevrimdışı verilerin nasıl yönetileceğini göstereceğiz.

Depolama alanı yalnızca dosyalar ve öğelerle ilgili değildir, başka veri türleri 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 bir NoSQL nesne depolama seçeneğidir.
  • WebStorage: Anahtar/değer dizesi çiftlerini, yerel depolama veya oturum depolamasını kullanarak depolamanın bir yoludur. Service Worker 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 açıklandığı şekilde.
ziyaret edin.

Desteklenen platformlarda Storage Manager API'yi kullanarak tüm cihaz depolama alanlarını yönetebilirsiniz. Cache Storage API'si ve IndexedDB, PWA'lar için kalıcı depolama alanına eşzamansız erişim sağlar ve ana iş parçacığı, web çalışanları ve hizmet çalışanlarından erişilebilir. Ağ kesintili olduğunda veya mevcut olmadığında PWA'ların güvenilir bir şekilde çalışmasında her ikisi de temel rol oynar. Peki ama her birini ne zaman kullanmalısınız?

HTML, CSS, JavaScript, resimler, videolar ve ses gibi bir URL aracılığıyla isteyerek erişebileceğiniz ağ kaynakları (ör. HTML, CSS, JavaScript, resimler, videolar ve ses) için Cache Storage API'sini kullanın.

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

IndexedDB

IndexedDB'yi kullanmak için önce bir veritabanı açın. Bu işlemle, yeni bir veritabanı yoksa yeni bir veritabanı oluşturulur. IndexedDB, eşzamansız bir API'dir ancak Promise değeri döndürmek yerine geri çağırmayı alır. Aşağıdaki örnekte, IndexedDB için Jake Archibald'ın 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 isterseniz idb kitaplığını kullanabilirsiniz.

Aşağıdaki örnekte yemek tariflerinin tutulduğu bir veritabanı oluşturulur.

Veritabanı oluşturma ve açma

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

  1. cookbook adlı 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ğırması içeren bir ilk kullanıma hazırlama nesnesi openDB() hizmetine iletildi. Veritabanı ilk kez yüklendiğinde veya yeni bir sürüme yükseltildiğinde geri çağırma işlevi çağrılır. İşlemlerin gerçekleştirilebileceği tek yer bu işlevdir. İşlemler arasında yeni nesne depoları (indexedDB'nin verileri düzenlemek için kullandığı yapılar) veya dizinler (üzerinde arama yapmak istediğiniz) oluşturulabilir. Veri taşıma işlemi de bu noktada gerçekleştirilmelidir. Genellikle upgrade() işlevi, veritabanının eski sürümüne göre her adımın sırayla gerçekleşmesini sağlamak için break ifadeleri 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');
     }
   }
  });
}

Örnek, cookbook veritabanında recipes adlı bir nesne deposu oluşturur. Bu nesne deposunda id özelliği mağazanın dizin anahtarı olarak ayarlanır. Ayrıca, type özelliğine göre type adlı başka bir dizin oluşturulur.

Şimdi, yeni oluşturulan nesne deposuna 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örmeyi bekleyin:

Safari ve Chrome, IndexedDB içeriğini gösteriyor.

Veri ekleme

IndexedDB, işlemleri kullanır. İşlemler, işlemleri birlikte gruplandırarak tek bir birim olarak gerçekleşir. Veritabanının her zaman tutarlı bir durumda olmasını sağlarlar. Uygulamanızın birden fazla kopyası çalışıyorsa aynı verilere aynı anda yazmayı önlemek açısından bunlar da kritik önem taşır. Veri eklemek için:

  1. mode, readwrite olarak ayarlanmış bir işlem başlatın.
  2. Verileri ekleyeceğiniz nesne deposunu alın.
  3. Kaydettiğiniz verileri kullanarak add() numaralı telefonu arayı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 isterseniz bunun yerine put() yöntemini çağırırsınız.

İşlemlerde, işlem başarıyla tamamlandığında sona eren veya işlem hatasıyla reddeden bir done taahhüdü vardır.

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

// 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;
}

Kurabiyeleri ekledikten sonra, tarifi diğer tariflerle birlikte veritabanında bulacaktır. Kimlik, indexDB tarafından otomatik olarak ayarlanır ve artar. Bu kodu iki kez çalıştırırsanız birbirinin aynısı iki çerez girişiniz olur.

Veriler alınıyor

IndexedDB'deki verileri şu şekilde alabilirsiniz:

  1. Bir işlem başlatın, nesne deposunu veya depoları ve isteğe bağlı olarak işlem türünü belirtin.
  2. O işlemden objectStore() adlı kişiyi arayın. Nesne mağazası adını belirttiğinizden emin olun.
  3. Almak istediğiniz anahtarı kullanarak get() adlı kişiyi arayın. Varsayılan olarak mağaza, anahtarını bir 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ın doğru şekilde depolanması ve akışı açısından özellikle önemlidir.

Depolama kapasitesi; Önbellek Depolama, IndexedDB, Web Depolama gibi tüm depolama seçenekleri arasında, hatta hizmet çalışanı dosyası ve bağımlıları arasında paylaşılır. Ancak kullanılabilir depolama alanı miktarı tarayıcıdan tarayıcıya değişir. Büyük ihtimalle tükenmezsiniz. siteler bazı tarayıcılarda megabaytlarca, hatta gigabaytlarca veri depolayabiliyordu. Örneğin Chrome, tarayıcının toplam disk alanının% 80'ine kadar kullanmasına izin verir ve tek bir kaynak, tüm disk alanının% 60'ına varan bir kısmını kullanabilir. Storage API'yi destekleyen tarayıcılarda uygulamanızın ne kadar depolama alanı kaldığını, kotasını ve kullanımını bilebilirsiniz. Aşağıdaki örnekte, tahmini kota ve kullanımı almak için Storage API kullanılmaktadır. Ardından, kullanılan yüzde ve kalan bayt miktarı hesaplanır. navigator.storage işlevinin, StorageManager örneğini döndürdüğünü unutmayın. Ayrı bir Storage arayüzü vardır ve kullanıcıların kafasını karıştırmak çok 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 Alanı bölümünü açarak sitenizin kotasını ve kullanılan depolama alanı miktarını kotaya göre ayrılmış şekilde görebilirsiniz.

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

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

Veri kalıcılığı

İşlem yapılmadığında veya depolama alanı yoğunluğu olduğunda verilerin otomatik olarak çıkarılmasını önlemek için tarayıcıdan uyumlu platformlarda kalıcı depolama alanı isteyebilirsiniz. İzin verilirse tarayıcı, verileri hiçbir zaman depolama alanından çıkarmaz. Bu koruma; hizmet çalışanı kaydını, IndexedDB veritabanlarını ve önbellek depolama alanındaki dosyaları kapsar. Yöneticilerin her zaman sorumlu olduğunu ve tarayıcı kalıcı depolama alanı vermiş olsa bile depolama alanını istedikleri zaman silebileceğini unutmayın.

Kalıcı depolama alanı isteğinde bulunmak için StorageManager.persist() çağırın. Önceden 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}`);
}

Ayrıca StorageManager.persisted() çağırarak geçerli kaynakta kalıcı depolama alanının zaten verilip verilmediğini de kontrol edebilirsiniz. Firefox, kullanıcıdan kalıcı depolama alanını kullanmak için izin ister. Chromium tabanlı tarayıcılar, içeriğin kullanıcı için önemini belirlemek için buluşsal bir yöntemle kalıcılık verir veya reddeder. Google Chrome için kriterlerden biri, örneğin PWA (Progresif Web Uygulaması) kurulumudur. Kullanıcı, işletim sisteminde PWA için bir simge yüklediyse tarayıcı kalıcı depolama alanı verebilir.

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

ziyaret edin.

API Tarayıcı desteği

Web Depolama

Tarayıcı Desteği

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

Kaynak

Dosya Sistemi Erişimi

Tarayıcı Desteği

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

Kaynak

Depolama Yöneticisi

Tarayıcı Desteği

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

Kaynak

Kaynaklar