IndexedDB'yi Kullanmayla İlgili En İyi Uygulamalar

Popüler bir durum yönetimi kitaplıkları olan IndexedDB arasında uygulama durumunu senkronize etmeye yönelik en iyi uygulamaları öğrenin.

Bir kullanıcı bir web sitesini veya uygulamayı ilk kez yüklediğinde, kullanıcı arayüzünü oluşturmak için kullanılan ilk uygulama durumunun oluşturulması genellikle oldukça fazla emek gerektirir. Örneğin, bazen uygulamanın kullanıcının istemci tarafında kimliğini doğrulaması ve daha sonra, sayfada görüntülemesi gereken tüm verilere sahip olmadan önce birkaç API isteğinde bulunması gerekir.

Uygulama durumunu IndexedDB'de depolamak, yinelenen ziyaretler için yükleme süresini kısaltmanın harika bir yolu olabilir. Uygulama, daha sonra arka planda herhangi bir API hizmetiyle senkronizasyon gerçekleştirebilir ve kullanıcı arayüzünü, eski-yeniden doğrula stratejisinden yararlanarak yeni verilerle gecikmeli olarak güncelleyebilir.

IndexedDB'nin bir başka iyi kullanımı da kullanıcı tarafından oluşturulan içeriğin sunucuya yüklenmeden önce geçici bir depolama alanı olarak veya uzak verilerin istemci tarafında önbelleği olarak ya da elbette her ikisi olarak depolanmasıdır.

Bununla birlikte, IndexedDB'yi kullanırken, API'leri yeni kullanmaya başlayan geliştiricilerin göz önünde bulundurmadığı birçok önemli nokta vardır. Bu makalede, sık sorulan sorular yanıtlanmakta ve IndexedDB'de verileri saklamaya devam ederken akılda tutulması gereken en önemli şeylerden bazıları gösterilmektedir.

Uygulamanızı öngörülebilir hale getirme

IndexedDB ile ilgili karmaşıklığın bir çok nedeni, sizin (geliştiricinin) üzerinde kontrol sahibi olmadığınız çok fazla faktör olmasıdır. Bu bölümde, IndexedDB ile çalışırken aklınızda bulundurmanız gereken birçok sorun ele alınmaktadır.

Tüm platformlarda her şey IndexedDB'de depolanamaz

Resim veya video gibi kullanıcı tarafından oluşturulan büyük dosyalar depoluyorsanız bunları File veya Blob nesneleri olarak depolamayı deneyebilirsiniz. Bu, bazı platformlarda çalışırken diğerlerinde başarısız olur. Özellikle iOS'teki Safari, Blob öğelerini IndexedDB'de depolayamaz.

Neyse ki Blob bir ArrayBuffer'a (veya bunun tersi) çok zor değildir. ArrayBuffer öğelerinin IndexedDB'de depolanması da son derece desteklenmektedir.

Bununla birlikte, Blob biriminin MIME türüne sahip olduğunu, ancak ArrayBuffer türünün böyle olmadığını unutmayın. Dönüşümü doğru bir şekilde yapmak için türü tamponla birlikte depolamanız gerekir.

Bir ArrayBuffer öğesini Blob biçimine dönüştürmek için Blob oluşturucuyu kullanmanız yeterlidir.

function arrayBufferToBlob(buffer, type) {
  return new Blob([buffer], { type: type });
}

Diğer yön ise biraz daha karmaşık ve eşzamansız bir süreçtir. Blob'u ArrayBuffer olarak okumak için bir FileReader nesnesi kullanabilirsiniz. Okuma bittiğinde okuyucuda bir loadend etkinliği tetiklenir. Bu süreci şu şekilde bir Promise içine alabilirsiniz:

function blobToArrayBuffer(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.addEventListener('loadend', () => {
      resolve(reader.result);
    });
    reader.addEventListener('error', reject);
    reader.readAsArrayBuffer(blob);
  });
}

Depolama alanına yazma başarısız olabilir

IndexedDB'ye yazma sırasında karşılaşılan hatalar çeşitli nedenlerle ortaya çıkabilir ve bazı durumlarda bu nedenler geliştirici olarak kontrolünüzün dışındadır. Örneğin, şu anda bazı tarayıcılar gizli tarama modundayken IndexedDB'ye yazmaya izin vermemektedir. Ayrıca, bir kullanıcının disk alanı neredeyse tükenmiş bir cihazda olması ve tarayıcının sizi herhangi bir şey depolamanıza kısıtlama getirme olasılığı da vardır.

Bu nedenle, IndexedDB kodunuzda her zaman doğru hata işlemeyi uygulamanız çok önemlidir. Bu aynı zamanda, uygulama durumunun bellekte tutulması (depolamaya ek olarak) genellikle iyi bir fikirdir. Böylece, özel tarama modunda çalışırken veya depolama alanı olmadığında kullanıcı arayüzü bozulmaz (depolama gerektiren diğer uygulama özelliklerinden bazıları çalışmayacak olsa bile).

Her IDBDatabase, IDBTransaction veya IDBRequest nesnesi oluşturduğunuzda error etkinliği için bir etkinlik işleyici ekleyerek IndexedDB işlemlerindeki hataları yakalayabilirsiniz.

const request = db.open('example-db', 1);
request.addEventListener('error', (event) => {
  console.log('Request error:', request.error);
};

Depolanan veriler kullanıcı tarafından değiştirilmiş veya silinmiş olabilir

Yetkisiz erişimi kısıtlayabileceğiniz sunucu tarafı veritabanlarından farklı olarak, istemci taraflı veritabanlarına tarayıcı uzantıları ve geliştirici araçları erişebilir ve bu veritabanları kullanıcı tarafından temizlenebilir.

Kullanıcıların yerel olarak depolanan verilerini değiştirmesi çok nadir olsa da, kullanıcıların bu verileri temizlemesi çok yaygın bir durumdur. Uygulamanızın bu durumların her ikisini de hata yapmadan işleyebilmesi önemlidir.

Depolanan veriler güncel olmayabilir

Önceki bölüme benzer şekilde, kullanıcı verilerde değişiklik yapmamış olsa bile depolama alanındaki veriler, kodunuzun eski bir sürümü (muhtemelen içinde hata içeren bir sürüm) tarafından yazılmış olabilir.

IndexedDB, şema sürümleri ve IDBOpenDBRequest.onupgradeneeded() yöntemi aracılığıyla yükseltme için yerleşik destek sunmaktadır. Ancak yine de yükseltme kodunuzu, önceki bir sürümden gelen (hata içeren bir sürüm dahil) kullanıcıyı işleyebilecek şekilde yazmanız gerekir.

Birim testleri, olası tüm yükseltme yollarının ve durumların manuel olarak test edilmesi çoğu zaman mümkün olmadığından burada çok yararlı olabilir.

Uygulamanızın performansını koruma

IndexedDB'nin temel özelliklerinden biri eşzamansız API'sidir. Ancak bu API'yi kullanırken performans konusunda endişelenmenize gerek olmadığını düşünmenize izin vermeyin. Uygun olmayan kullanımın ana iş parçacığını yine de engelleyebileceği, bunun da duraklamaya ve yanıt verememesine neden olabileceği birkaç durum vardır.

Genel kural olarak IndexedDB'ye yapılan okuma ve yazma işlemleri, erişilen veriler için gerekenden daha büyük olmamalıdır.

IndexedDB, büyük, iç içe yerleştirilmiş nesnelerin tek bir kayıt olarak depolanmasını mümkün kılsa da (ve geliştirici açısından bunu yapmak kabul edilebilir bir uygulamadır) bu uygulamadan kaçınılmalıdır. Bunun nedeni, IndexedDB'nin bir nesneyi depoladığında öncelikle bu nesnenin yapılandırılmış klonunu oluşturması gerekmesi ve yapılandırılmış klonlama sürecinin ana iş parçacığında gerçekleşmesidir. Nesne ne kadar büyükse engelleme süresi de o kadar uzun olur.

Popüler durum yönetim kitaplıklarının (Redux gibi) çoğu durum ağacınızın tamamını tek bir JavaScript nesnesi olarak yöneterek çalıştığı için bu, uygulama durumunun IndexedDB'de nasıl korunacağını planlarken bazı zorluklar oluşturur.

Durumu bu şekilde yönetmenin pek çok avantajı olsa da (ör.kodunuzda gerekçe oluşturmayı ve hata ayıklamayı kolaylaştırabilirsiniz) ve tüm durum ağacını IndexedDB'de tek bir kayıt olarak saklamak cazip ve kullanışlı olabilir. Ancak bunu her değişiklikten sonra yapmak (kısıtlanmış/geri sarılmış olsa bile) ana iş parçacığının gereksiz yere engellenmesine neden olur, bazı durumlarda sekmenin yanıt vermeme hatasına bile yol açabilir.

Durum ağacının tamamını tek bir kayıtta depolamak yerine, ayrı kayıtlara bölmeniz ve yalnızca gerçekten değişen kayıtları güncellemeniz gerekir.

IndexedDB'de resim, müzik veya video gibi büyük öğeler depoluyorsanız da aynı durum geçerlidir. Her öğeyi daha büyük bir nesnenin içinde değil, kendi anahtarıyla depolayın. Böylece yapılandırılmış verileri, ikili dosyayı alma ücreti ödemeden alabilirsiniz.

Çoğu en iyi uygulamada olduğu gibi bu da "ya hep ya hiç" kuralı değildir. Bir durum nesnesini bölmenin ve yalnızca minimum değişiklik kümesini yazmanın uygun olmadığı durumlarda, verileri alt ağaçlara bölmek ve durum ağacının tamamını yazmak her zaman yalnızca bunların yazılması tercih edilir. Küçük iyileştirmeler, hiç iyileştirme yapmamaktan iyidir.

Son olarak, yazdığınız kodun performans etkisini her zaman ölçmeniz gerekir. IndexedDB'ye yapılan küçük yazma işlemlerinin büyük boyutlu yazmalardan daha iyi performans göstereceği doğru olsa da bu yalnızca, IndexedDB'ye yapılan yazmaların aslında ana iş parçacığını engelleyen ve kullanıcı deneyimini olumsuz yönde etkileyen uzun görevlere yol açması durumunda önemli olur. Ne için optimizasyon yaptığınızı anlayabilmeniz için ölçüm yapmak önemlidir.

Sonuçlar

Geliştiriciler, hem oturumlardaki durumun hem de sonraki ziyaretlerde ilk durumun yüklenmesi için gereken süreyi azaltarak uygulamalarının kullanıcı deneyimini iyileştirmek için IndexedDB gibi istemci depolama mekanizmalarından yararlanabilir.

IndexedDB'nin doğru şekilde kullanılması kullanıcı deneyimini önemli ölçüde iyileştirebilir. Ancak yanlış kullanım ya da hata durumlarının ele alınmaması, bozuk uygulamalara ve mutsuz kullanıcılara yol açabilir.

İstemci depolama alanı sizin kontrolünüz dışında birçok faktöre bağlı olduğundan, başlangıçta ortaya çıkma olasılığı düşük görünseler bile kodunuzun iyi test edilmesi ve hataları doğru şekilde ele alması son derece önemlidir.