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:
cookbook
adında yeni bir IndexedDB veritabanı oluşturmak içinopenDB
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.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. Genellikleupgrade()
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 üzerebreak
ifadesi içermeyen birswitch
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:
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:
mode
öğesininreadwrite
olarak ayarlandığı bir işlem başlatın.- Verileri ekleyeceğiniz nesne deposunu alın.
- 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 yerineput()
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:
- Bir işlem başlatın ve nesne deposunu veya depoları ve isteğe bağlı olarak işlem türünü belirtin.
- Bu işlemde
objectStore()
adlı kişiyi ara. Nesne deposu adını belirttiğinizden emin olun. - 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.
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.
API Tarayıcısı desteği
Web Depolama
Dosya Sistemi Erişimi
Depolama Yöneticisi