IndexedDB'yi Kullanmayla İlgili En İyi Uygulamalar

IndexedDB ve popüler durum yönetimi kitaplıkları arasında uygulama durumunu senkronize etmeyle ilgili en iyi uygulamaları öğrenin.

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 durumunu oluşturmak için genellikle pek çok çalışma gerekir. Örneğin, bazen uygulamanın sayfada görüntülemesi gereken tüm verilere sahip olmadan önce kullanıcı istemci tarafında kimlik doğrulaması yapması ve ardından birkaç API isteği göndermesi gerekir.

Uygulama durumunu IndexedDB'de depolamak, tekrarlanan ziyaretler için yükleme süresini hızlandırmanın harika bir yolu olabilir. Uygulama, daha sonra arka plandaki tüm API hizmetleriyle senkronize olup kullanıcı arayüzünü yeni verilerle gecikmeli olarak güncelleyebilir. Bunun için yeniden doğrulama yaparken eski bir strateji kullanır.

IndexedDB'nin bir diğer iyi kullanım amacı da kullanıcı tarafından oluşturulan içeriği ya sunucuya yüklenmeden önce geçici bir depo olarak ya da uzak verilerin istemci tarafında önbelleği veya tabii ki her ikisini de depolamaktır.

Bununla birlikte, IndexedDB'yi kullanırken API'leri yeni kullanmaya başlayan geliştiricilerin göz önünde bulundurması gereken birçok önemli nokta vardır. Bu makalede, sık sorulan sorular yanıtlanmakta ve IndexedDB'de veri muhafaza ederken unutulmaması gereken en önemli noktalardan bazıları ele alınmaktadır.

Uygulamanızı tahmin edilebilir tutma

IndexedDB ile ilgili karmaşık durumların çoğunun nedeni, sizin (geliştirici) kontrol edemediğiniz çok fazla faktör olmasıdır. Bu bölümde, IndexedDB ile çalışırken aklınızda bulundurmanız gereken sorunların birçoğu incelenmektedir.

Her şey, tüm platformlarda IndexedDB'de depolanamaz

Kullanıcı tarafından oluşturulan resim veya video gibi büyük boyutlu dosyalar depoluyorsanız bunları File veya Blob nesneleri olarak depolamayı deneyebilirsiniz. Bu, bazı platformlarda işe yarar ancak bazılarında başarısız olur. iOS'teki Safari, Blob öğelerini IndexedDB'de depolayamaz.

Neyse ki Blob öğesini ArrayBuffer değerine (veya tam tersi) dönüştürmek çok zor değildir. ArrayBuffer öğelerinin IndexedDB'de depolanması çok iyi desteklenir.

Ancak, Blob MIME türüne sahipken ArrayBuffer türünün olmadığını unutmayın. Dönüşümü doğru şekilde yapmak için türü arabellekle birlikte depolamanız gerekir.

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şıktır ve eşzamansız bir süreçtir. Blobu ArrayBuffer olarak okumak için FileReader nesnesini kullanabilirsiniz. Okuma sona erdiğinde, okuyucuda bir loadend etkinliği tetiklenir. Bu işlemi Promise içinde şu şekilde sarmalayabilirsiniz:

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 işlemi başarısız olabilir

IndexedDB'ye yazarken hatalar çeşitli nedenlerle ortaya çıkabilir ve bazı durumlarda bu nedenler geliştirici olarak sizin 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, kullanıcının disk alanı bitmek üzere olan bir cihazda olma ihtimali de vardır. Bu durumda tarayıcı, herhangi bir şey depolamanızı kısıtlar.

Bu nedenle, IndexedDB kodunuzda her zaman doğru hata işlemeyi uygulamanız çok önemlidir. Bu aynı zamanda, özel tarama modunda çalışırken veya depolama alanı kullanılamadığında (depolama alanı gerektiren diğer uygulama özelliklerinden bazıları çalışmasa bile) kullanıcı arayüzü bozulmaması için uygulama durumunu depolamanın da bellekte tutulmasının genellikle iyi bir fikir olduğu anlamına gelir.

Her IDBDatabase, IDBTransaction veya IDBRequest nesnesi oluşturduğunuzda error etkinliği için bir etkinlik işleyici ekleyerek IndexedDB işlemlerinde 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ı tarayıcı uzantıları ve geliştirici araçları tarafından erişilebilir ve kullanıcı tarafından temizlenebilir.

Kullanıcılar yerel olarak depolanan verilerinde değişiklik yapmasa da bunları temizlemesi yaygın bir uygulamadır. Uygulamanızın bu durumların her ikisini de hata vermeden halledebilmesi önemlidir.

Depolanan veriler güncel olmayabilir

Önceki bölüme benzer şekilde, kullanıcı verileri değiştirmemiş olsa bile, depolama alanındaki veriler kodunuzun eski bir sürümü (muhtemelen 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 desteğe sahiptir ancak yükseltme kodunuzu, önceki bir sürümden (hata içeren sürüm de dahil) gelen kullanıcıları işleyebilecek şekilde yazmanız gerekir.

Olası tüm yükseltme yollarını ve durumları manuel olarak test etmek genellikle uygun olmadığından birim testleri burada çok faydalı olabilir.

Uygulamanızın performansını koruma

IndexedDB'nin en önemli özelliklerinden biri, eşzamansız API'sidir. Ancak yine de bu API'yi kullanırken performans konusunda endişelenmeniz gerekmediğini düşünmek sizi aldatmasın. Hatalı kullanımın ana iş parçacığını yine de engelleyebileceği ve bu durum, olumsuzluklara ve yanıt vermemeye yol açabilecek bazı durumlar vardır.

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

IndexedDB, iç içe yerleştirilmiş büyük nesnelerin tek bir kayıt olarak depolanmasını mümkün kılsa da (bunu yapmanın geliştirici açısından oldukça kullanışlı olduğu kabul edilir) ancak bu uygulamadan kaçınılmalıdır. Bunun nedeni, IndexedDB bir nesneyi depolarken önce bu nesnenin yapılandırılmış bir klonunu oluşturması ve yapılandırılmış klonlama sürecinin ana iş parçacığında gerçekleşmesidir. Nesne ne kadar büyük olursa engelleme süresi de o kadar uzun olur.

Popüler durum yönetimi 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ığından, bu durum, uygulama durumunun IndexedDB'de nasıl tutulacağını planlarken bazı zorlukları beraberinde getirir.

Durumu bu şekilde yönetmenin pek çok avantajı olsa da (ör. kodunuzda akıl yürütmeyi ve hata ayıklamayı kolaylaştırır) ve tüm durum ağacını IndexedDB'de tek bir kayıt olarak saklamak cazip ve kullanışlı olabilir. Ancak bu işlemi her değişiklikten sonra (kısıtlanmış/deboy kaldırılmış olsa bile) yapmak ana iş parçacığının gereksiz şekilde engellenmesine veya bazı durumlarda sekmenin kilitlenmesine neden olur. Hatta sekmenin kilitlenme olasılığını da artırır.

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

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

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

Son olarak, yazdığınız kodun her zaman performans üzerindeki etkisini ölçüyor olmanız gerekir. IndexedDB'ye yapılan küçük yazma işlemlerinin büyük yazmalardan daha iyi performans göstereceği doğru olsa da bu durum yalnızca, uygulamanızın yapmakta olduğu IndexedDB'ye yazma işleminin ana iş parçacığını engelleyen ve kullanıcı deneyimini olumsuz etkileyen uzun görevlere yol açması durumunda önemlidir. Ne için optimizasyon yaptığınızı anlamak için ölçüm yapmak önemlidir.

Sonuçlar

Geliştiriciler, IndexedDB gibi istemci depolama mekanizmalarından yararlanarak uygulamalarının kullanıcı deneyimini iyileştirmek için hem durumu oturumlar genelinde sürdürebilir hem de tekrarlanan ziyaretlerde ilk durumu yüklemek için gereken süreyi kısaltabilir.

IndexedDB'yi doğru şekilde kullanmak kullanıcı deneyimini önemli ölçüde iyileştirebilir ancak yanlış kullanılması veya hata durumlarını ele almamak, uygulamaların bozulmasına ve kullanıcıların memnun olmamasına yol açabilir.

İstemci depolaması sizin kontrolünüz dışında birçok faktörü içerdiğinden, kodunuzun iyi test edilmesi ve başlangıçta oluşmayacak gibi görünebilecek hataları düzgün şekilde gidermesi son derece önemlidir.