Web için depolama alanı

Tarayıcıda veri depolamak için birçok farklı seçenek vardır. İhtiyaçlarınız için en uygun olanı hangisi?

Hareket halindeyken internet bağlantıları kesintili olabilir veya hiç olmayabilir. Bu nedenle, progresif web uygulamalarında çevrimdışı destek ve güvenilir performans yaygın olarak bulunur. Mükemmel kablosuz ortamlarda bile önbelleğe alma ve diğer depolama tekniklerinin dikkatli bir şekilde kullanılması, kullanıcı deneyimini önemli ölçüde iyileştirebilir. Statik uygulama kaynaklarınızı (HTML, JavaScript, CSS, resimler vb.) ve verilerinizi (kullanıcı verileri, haber makaleleri vb.) önbelleğe almanın çeşitli yolları vardır. Ancak en iyi çözüm hangisidir? Ne kadar veri saklayabilirsiniz? Bu durumu nasıl önleyebilirsiniz?

Hangisini kullanmalıyım?

Kaynakları depolamaya ilişkin genel bir öneri aşağıda verilmiştir:

IndexedDB, OPFS ve Cache Storage API tüm modern tarayıcılarda desteklenir. Asenkron oldukları için ana iş parçacığını engellemezler (ancak OPFS'nin yalnızca web çalışanlarında kullanılabilen senkron bir varyantı da vardır). window nesnesinden, web çalışanlarından ve hizmet çalışanlarından erişilebildiği için kodunuzun herhangi bir yerinde kullanılabilirler.

Diğer depolama mekanizmaları?

Tarayıcıda kullanılabilecek başka depolama mekanizmaları da vardır ancak bunların kullanımı sınırlıdır ve önemli performans sorunlarına neden olabilirler.

SessionStorage, sekmeye özeldir ve sekmenin kullanım ömrüyle sınırlıdır. Oturuma özgü az miktarda bilgiyi (ör. IndexedDB anahtarı) depolamak için yararlı olabilir. Eşzamanlı olduğu ve ana iş parçacığını engelleyeceği için dikkatli kullanılmalıdır. Yaklaşık 5 MB ile sınırlıdır ve yalnızca dizeler içerebilir. Sekmeye özel olduğundan web çalışanları veya hizmet çalışanları tarafından erişilemez.

LocalStorage, senkron olduğu ve ana iş parçacığını engelleyeceği için kullanılmamalıdır. Yaklaşık 5 MB ile sınırlıdır ve yalnızca dizeler içerebilir. LocalStorage'a web worker'lardan veya service worker'lardan erişilemez.

Çerezlerin kullanım alanları vardır ancak depolama için kullanılmamalıdır. Çerezler her HTTP isteğiyle birlikte gönderilir. Bu nedenle, az miktarda veriden fazlasını depolamak her web isteğinin boyutunu önemli ölçüde artırır. Bunlar eşzamanlıdır ve web çalışanlarından erişilemez. LocalStorage ve SessionStorage gibi çerezler de yalnızca dizelerle sınırlıdır.

File System Access API, kullanıcıların yerel dosya sistemlerindeki dosyaları okuyup düzenleyebilmesi için tasarlanmıştır. Bir sayfanın herhangi bir yerel dosyayı okuyabilmesi veya dosyaya yazabilmesi için kullanıcının izin vermesi gerekir. Ayrıca, IndexedDB'de bir dosya işleyicisi önbelleğe alınmadığı sürece izinler oturumlar arasında kalıcı olmaz. File System Access API, bir dosyayı açmanız, değiştirmeniz ve ardından değişiklikleri dosyaya geri kaydetmeniz gereken düzenleyiciler gibi kullanım alanları için en uygun API'dir.

File System API ve FileWriter API, dosyaları korumalı alan dosya sistemine okuma ve yazma yöntemleri sağlar. Asenkron olmasına rağmen yalnızca Chromium tabanlı tarayıcılarda kullanılabildiği için önerilmez.

Ne kadar depolayabilirim?

Kısacası, çok fazla. En az birkaç yüz megabayt, hatta yüzlerce gigabayt veya daha fazla. Tarayıcı uygulamaları farklılık gösterir ancak kullanılabilir depolama alanı miktarı genellikle cihazda kullanılabilir depolama alanı miktarına bağlıdır.

  • Chrome, tarayıcının toplam disk alanının% 80'ini kullanmasına izin verir. Bir kaynak, toplam disk alanının en fazla% 60'ını kullanabilir. Kullanılabilir maksimum kotayı belirlemek için StorageManager API'yi kullanabilirsiniz. Diğer Chromium tabanlı tarayıcılar farklı olabilir.
    • Chrome, gizli modda bir kaynağın kullanabileceği depolama alanını toplam disk alanının yaklaşık% 5'iyle sınırlar.
    • Kullanıcı Chrome'da "Tüm pencereleri kapattığınızda çerezleri ve site verilerini temizle" ayarını etkinleştirdiyse depolama alanı kotası önemli ölçüde düşürülerek en fazla yaklaşık 300 MB'a çıkarılır.
  • Firefox, tarayıcının boş disk alanının% 50'sini kullanmasına izin verir. Bir eTLD+1 grubu (ör. example.com, www.example.com ve foo.bar.example.com) en fazla 2 GB kullanabilir. Hâlâ ne kadar alan olduğunu belirlemek için StorageManager API'yi kullanabilirsiniz.
  • Safari (hem masaüstü hem de mobil) yaklaşık 1 GB'a izin veriyor gibi görünüyor. Sınıra ulaşıldığında Safari, kullanıcıya istem gösterir ve sınırı 200 MB'lık artışlarla yükseltir. Bu konuda resmi bir doküman bulamadım.
    • Mobil Safari'de ana ekrana bir PWA eklenirse yeni bir depolama alanı oluşturulur ve PWA ile mobil Safari arasında hiçbir şey paylaşılmaz. Yüklü bir PWA için kotaya ulaşıldığında ek depolama alanı isteğinde bulunmanın bir yolu yoktur.

Geçmişte, bir site belirli bir depolanan veri eşiğini aştığında tarayıcı, kullanıcıdan daha fazla veri kullanma izni vermesini isterdi. Örneğin, kaynak 50 MB'tan fazla alan kullanırsa tarayıcı, kullanıcıdan 100 MB'a kadar depolama izni vermesini ister ve 50 MB'lık artışlarla tekrar sorar.

Günümüzde çoğu modern tarayıcı, kullanıcıya istem göstermez ve bir sitenin ayrılan kotasına kadar kullanmasına izin verir. Depolama alanı kotası aşıldığında ayrılan kotanın artırılması için izin isteyen Safari bu durumun istisnası gibi görünüyor. Bir kaynak, ayrılan kotasından daha fazla kullanmaya çalışırsa veri yazma girişimleri başarısız olur.

Kullanılabilir depolama alanını nasıl kontrol edebilirim?

Birçok tarayıcıda, kaynağın kullanabileceği depolama alanı miktarını ve ne kadar depolama alanı kullandığını belirlemek için StorageManager API'yi kullanabilirsiniz. IndexedDB ve Cache API tarafından kullanılan toplam bayt sayısını bildirir ve yaklaşık olarak kalan depolama alanını hesaplamayı mümkün kılar.

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.`);
}

Kota aşımı hatalarını yakalamanız gerekir (aşağıya bakın). Bazı durumlarda, kullanılabilir kota, gerçek depolama alanını aşabilir.

İnceleme

Geliştirme sırasında, farklı depolama türlerini incelemek ve depolanan tüm verileri temizlemek için tarayıcınızın geliştirici araçlarını kullanabilirsiniz.

Chrome 88'de, Depolama Bölmesi'nde sitenin depolama kotasını geçersiz kılmanıza olanak tanıyan yeni bir özellik eklendi. Bu özellik, farklı cihazları simüle etmenize ve uygulamalarınızın disk alanı az olduğunda nasıl davrandığını test etmenize olanak tanır. Uygulama, ardından Depolama'ya gidin, Özel depolama alanı kotasını simüle et onay kutusunu etkinleştirin ve depolama alanı kotasını simüle etmek için geçerli bir sayı girin.

Bu kılavuz üzerinde çalışırken olabildiğince fazla depolama alanını hızlı bir şekilde kullanmak için basit bir araç yazdım. Bu, farklı depolama mekanizmalarını denemenin ve kotanızın tamamını kullandığınızda ne olacağını görmenin hızlı bir yoludur.

Kotayı aşma durumunda ne yapmalıyım?

Kotayı aştığınızda ne yapmalısınız? En önemlisi, QuotaExceededError veya başka bir şeyden kaynaklanan yazma hatalarını her zaman yakalamalı ve işlemelisiniz. Ardından, uygulama tasarımınıza bağlı olarak bu durumu nasıl ele alacağınıza karar verin. Örneğin, uzun süredir erişilmeyen içerikleri silin, boyuta göre verileri kaldırın veya kullanıcılara silmek istedikleri öğeleri seçme olanağı sunun.

Hem IndexedDB hem de Cache API, kullanılabilir kotayı aştığınızda DOMError adlı bir hata QuotaExceededError oluşturur.

IndexedDB

Kaynak, kotasını aşmışsa IndexedDB'ye yazma girişimleri başarısız olur. İşlemin onabort() işleyicisi, bir etkinlik iletilerek çağrılır. Etkinlik, hata özelliğinde bir DOMException içerecek. Hata name kontrol ediliyor. QuotaExceededError döndürülür.

const transaction = idb.transaction(['entries'], 'readwrite');
transaction.onabort = function(event) {
  const error = event.target.error; // DOMException
  if (error.name == 'QuotaExceededError') {
    // Fallback code goes here
  }
};

Cache API

Kaynak kotasını aşmışsa Cache API'ye yazma girişimleri QuotaExceededError DOMException ile reddedilir.

try {
  const cache = await caches.open('my-cache');
  await cache.add(new Request('/sample1.jpg'));
} catch (err) {
  if (error.name === 'QuotaExceededError') {
    // Fallback code goes here
  }
}

Tahliye nasıl çalışır?

Web depolama alanı, "En İyi Çaba" ve "Kalıcı" olmak üzere iki kategoriye ayrılır. En iyi çaba, depolama alanının tarayıcı tarafından kullanıcıyı kesintiye uğratmadan temizlenebileceği ancak uzun vadeli veya kritik veriler için daha az dayanıklı olduğu anlamına gelir. Depolama alanı azaldığında kalıcı depolama alanı otomatik olarak temizlenmez. Kullanıcının bu depolama alanını manuel olarak temizlemesi (tarayıcı ayarları üzerinden) gerekir.

Bir sitenin verileri (IndexedDB, Cache API vb. dahil) varsayılan olarak en iyi çaba kategorisine girer. Bu, bir site kalıcı depolama isteğinde bulunmadığı sürece tarayıcının site verilerini kendi takdirine bağlı olarak çıkarabileceği (ör. cihaz depolama alanı azaldığında) anlamına gelir.

En iyi girişim için tahliye politikası şöyledir:

  • Chromium tabanlı tarayıcılar, tarayıcının alanı kalmadığında verileri silmeye başlar. En son kullanılan kaynaklardaki tüm site verileri önce temizlenir, ardından tarayıcı sınırın üzerinde olmadığı sürece bir sonraki kaynak temizlenir.
  • Firefox, kullanılabilir disk alanı dolduğunda verileri silmeye başlar. Önce en son kullanılmayan kaynakla ilgili tüm site verilerini, ardından tarayıcı sınırın üzerinde olmadığı sürece bir sonraki site verilerini temizler.
  • Safari daha önce verileri silmiyordu ancak kısa süre önce tüm yazılabilir depolama alanları için yedi günlük yeni bir sınır uyguladı (aşağıya bakın).

iOS ve iPadOS 13.4 ile macOS'teki Safari 13.1'den itibaren, IndexedDB, hizmet çalışanı kaydı ve Cache API dahil olmak üzere tüm komut dosyası yazılabilir depolama alanları için yedi günlük bir sınır uygulanmaktadır. Bu durumda, kullanıcı siteyle etkileşimde bulunmazsa Safari, yedi günlük kullanımdan sonra önbellekteki tüm içerikleri kaldırır. Bu kaldırma politikası, ana ekrana eklenen yüklü PWA'lar için geçerli değildir. Ayrıntılı bilgi için WebKit blog'undaki Full Third-Party Cookie Blocking and More (Üçüncü Taraf Çerezlerinin Tamamen Engellenmesi ve Diğerleri) başlıklı makaleyi inceleyin.

Depolama paketleri

Storage Buckets API'nin temel amacı, sitelere birden fazla depolama paketi oluşturma olanağı tanımaktır. Tarayıcı, her paketi diğer paketlerden bağımsız olarak silebilir. Bu sayede geliştiriciler, en değerli verilerin silinmemesini sağlamak için çıkarma önceliğini belirleyebilir.

Bonus: IndexedDB için neden sarmalayıcı kullanmalısınız?

IndexedDB, kullanımdan önce önemli ölçüde kurulum gerektiren düşük seviyeli bir API'dir. Bu durum, özellikle düşük karmaşıklıkta verilerin depolanması açısından zahmetli olabilir. Çoğu modern söz tabanlı API'nin aksine, bu API etkinlik tabanlıdır. IndexedDB için idb gibi Promise sarmalayıcılar, güçlü özelliklerin bir kısmını ve daha da önemlisi IndexedDB kitaplığıyla birlikte gelen karmaşık mekanizmaları (ör. işlemler, şema sürümü oluşturma) gizler.

Bonus: SQLite Wasm

Web SQL desteği sonlandırılıp Chrome'dan kaldırıldıktan sonra Google, SQLite tabanlı bir Web SQL alternatifi sunmak için popüler SQLite veritabanının bakımcılarıyla birlikte çalıştı. Nasıl kullanılacağıyla ilgili ayrıntılar için SQLite Wasm in the browser backed by the Origin Private File System başlıklı makaleyi inceleyin.

Sonuç

Sınırlı depolama alanı ve kullanıcıya daha fazla veri depolaması için istem gönderme günleri geride kaldı. Siteler, çalışmak için ihtiyaç duydukları tüm kaynakları ve verileri etkili bir şekilde depolayabilir. StorageManager API'yi kullanarak ne kadar alanınız olduğunu ve ne kadarını kullandığınızı belirleyebilirsiniz. Ayrıca, kullanıcı kaldırmadığı sürece kalıcı depolama alanı ile verileri silinmekten koruyabilirsiniz.

Ek kaynaklar

Teşekkürler

Bu kılavuzu inceledikleri için Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink ve Victor Costan'a teşekkür ederiz. Bu makalenin temelini oluşturan orijinal makaleleri yazan Eiji Kitamura, Addy Osmani ve Marc Cohen'e teşekkür ederiz. Eiji, mevcut davranışı doğrulamak için yararlı olan Browser Storage Abuser adlı faydalı bir araç yazdı. Bu sayede, mümkün olduğunca fazla veri depolayabilir ve tarayıcınızdaki depolama sınırlarını görebilirsiniz. Depolama sınırlarını belirlemek için Safari'yi inceleyen François Beaufort'a ve 2024'te kaynak özel dosya sistemi, depolama paketleri, SQLite Wasm ve genel içerik güncellemesi hakkında bilgi ekleyen Thomas Steiner'a teşekkür ederiz.