Web için depolama alanı

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

Hareket halindeyken internet bağlantıları kesintili olabilir veya olmayabilir. Bu nedenle, progresif web uygulamalarında çevrimdışı destek ve güvenilir performans ortak özelliklerdir. Mükemmel kablosuz ortamlarda bile önbelleğe alma ve diğer depolama tekniklerinin bilinçli kullanımı, 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 birkaç yolu vardır. Peki en iyi çözüm hangisidir? Ne kadar saklayabilirsiniz? Kiracının tahliye edilmesini nasıl önlersiniz?

Ne kullanmalıyım?

Kaynakları depolamaya yönelik genel önerimiz:

IndexedDB, OPFS ve Cache Storage API her modern tarayıcıda desteklenir. Asenkrondur ve ana iş parçacığını engellemez (ancak OPFS'nin yalnızca web çalışanlarında kullanılabilen senkron bir varyantı da vardır). Bu kaynaklara window nesnesi, web işçileri ve hizmet işçilerinden erişilebilir. Böylece, bunları kodunuzun herhangi bir yerinde kullanabilirsiniz.

Diğer depolama mekanizmaları ne olacak?

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

SessionStorage, sekmeye özeldir ve sekmenin kullanım ömrünü kapsar. IndexedDB anahtarı gibi oturuma özgü küçük miktarda bilgi 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 dize içerebilir. Sekmeye özel olduğu için web işçilerinden veya hizmet işçilerinden erişilemez.

Senkronize olduğu ve ana iş parçacığını engellediği için LocalStorage'dan kaçınılmalıdır. Yaklaşık 5 MB ile sınırlıdır ve yalnızca dize içerebilir. LocalStorage'a web çalışanlarından veya hizmet çalışanlarından erişilemez.

Çerezlerin kullanım alanları vardır, ancak depolama için kullanılmamalıdırlar. Çerezler her HTTP isteğiyle gönderilir. Bu nedenle, az miktarda veriden daha fazlasını depolamak, her web isteğinin boyutunu önemli ölçüde artırır. Bu işlevler 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ı okumasını ve düzenlemesini sağlamak için tasarlanmıştır. Bir sayfanın yerel bir dosyayı okuyabilmesi veya dosyaya yazabilmesi için kullanıcının izin vermesi gerekir. Ayrıca, IndexedDB'de bir dosya tutamaç önbelleğe alınmadığı sürece izinler oturumlar arasında devam ettirilmez. 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, korumalı bir dosya sisteminde dosya 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 depolama alanı kullanabilirim?

Özetle, çok. En az birkaç yüz megabayt, hatta yüzlerce gigabayt veya daha fazla olabilir. Tarayıcı uygulamaları değişiklik gösterir, ancak kullanılabilir depolama alanı miktarı genellikle cihazdaki kullanılabilir depolama alanına bağlıdır.

  • Chrome, tarayıcının toplam disk alanının% 80'ine kadarını kullanmasına izin verir. Bir kaynak, toplam disk alanının %60'ına kadarını kullanabilir. Kullanılabilir maksimum kotayı belirlemek için StorageManager API'yi kullanabilirsiniz. Chromium tabanlı diğer tarayıcılar farklı olabilir.
    • Chrome, gizli modda bir kaynağın kullanabileceği depolama alanını toplam disk alanının yaklaşık %5'ine düşürür.
    • Kullanıcı Chrome'da "Tüm pencereleri kapattığımda çerezleri ve site verilerini temizle" seçeneğini etkinleştirdiyse depolama kotası önemli ölçüde azaltılarak maksimum 300 MB olacak şekilde düşürülür.
  • Firefox, tarayıcının boş disk alanının %50'sine kadarını kullanmasına izin verir. Bir eTLD+1 grubu (ör. example.com, www.example.com ve foo.bar.example.com) 2 GB'a kadar kullanabilir. Hâlâ ne kadar kullanılabilir alan olduğunu belirlemek için StorageManager API'yi kullanabilirsiniz.
  • Safari'nin (hem masaüstü hem de mobil) yaklaşık 1 GB alana izin verdiği görülüyor. Sınıra ulaşıldığında Safari, sınırı 200 MB'lık artışlarla artırarak kullanıcıdan onay ister. Bu konuda resmi bir doküman bulamadım.
    • Mobil Safari'de ana ekrana eklenen bir PWA yeni bir depolama kapsayıcısı oluşturur ve PWA ile mobil Safari arasında hiçbir şey paylaşılmaz. Yüklenen bir PWA için kota dolduğunda ek depolama alanı isteğinde bulunamazsınız.

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

Günümüzde çoğu modern tarayıcı, kullanıcıdan kullanıcıya istem göndermemektedir ve sitenin kendisine ayrılan kotasını aşmasına izin verir. Bunun istisnası Safari'dir. Safari, depolama alanı kotası aşıldığında ayrılan kotayı artırma izni ister. Bir kaynak, kendisine tahsis edilen kotasından daha fazlasını kullanmaya çalışırsa sonraki veri yazma denemeleri başarısız olur.

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

Birçok tarayıcıda StorageManager API'yi kullanarak kaynağın kullanabileceği depolama alanı miktarını ve kaynağın ne kadar depolama alanı kullandığını öğrenebilirsiniz. IndexedDB ve Cache API tarafından kullanılan toplam bayt sayısını bildirir ve kullanılabilir yaklaşık 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 kotanın mevcut depolama alanını aşması mümkündür.

İnceleme

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

Chrome 88'de, Depolama Alanı bölmesinde sitenin depolama alanı kotasını geçersiz kılmanıza olanak tanıyan yeni bir özellik eklendi. Bu özellik, farklı cihazları simüle etmenize ve disk kullanılabilirliği düşük senaryolarda uygulamalarınızın davranışını test etmenize olanak tanır. Uygulama'ya, 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 kullanmaya çalışmak için basit bir araç yazdım. Farklı depolama mekanizmalarını denemek ve kotanızın tamamını kullandığınızda neler olduğunu görmek için hızlı bir yöntemdir.

Kotanın aşılmasıyla ilgili süreç nasıl ele alınır?

Kotayı aştığınızda ne yapmalısınız? En önemlisi, QuotaExceededError veya başka bir şey olsun, yazma hatalarını her zaman yakalayıp ele almanız gerekir. Ardından, uygulama tasarımınıza bağlı olarak bu sorunu nasıl ele alacağınıza karar verin. Örneğin, uzun süredir erişilmeyen içeriği silebilir, verileri boyuta göre kaldırabilir veya kullanıcılara silmek istedikleri bilgileri seçmeleri için bir yöntem sunabilirsiniz.

Kullanılabilir kotayı aştığınızda hem IndexedDB hem de Cache API, QuotaExceededError adlı bir DOMError atar.

IndexedDB

Kaynak, kotasını aştıysa IndexedDB'ye yazma denemeleri başarısız olur. İşlemin onabort() işleyicisi çağrılır ve bir etkinlik iletilir. Etkinlik, hata mülkünde bir DOMException içerir. name hatasını kontrol etmek QuotaExceededError sonucunu döndürü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ştıysa 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
  }
}

Kiracı çıkarma işlemi nasıl gerçekleşir?

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

Varsayılan olarak, bir sitenin verileri (IndexedDB, Cache API vb. dahil) en iyi çaba kategorisine girer. Diğer bir deyişle, bir site kalıcı depolama alanı istemediği sürece tarayıcı, site verilerini kendi takdirine bağlı olarak kaldırabilir (ör. cihaz depolama alanı düşük olduğunda).

En iyi çaba için tahliye politikası:

  • Chromium tabanlı tarayıcılar, tarayıcıda yer kalmadığında verileri çıkarmaya başlar. Önce en son kullanılmayan kaynaktaki tüm site verileri, ardından tarayıcı sınırı aşmayana kadar bir sonraki kaynaktaki veriler silinir.
  • Firefox, kullanılabilir disk alanı dolduğunda verileri çıkarmaya başlar. Tarayıcı sınırı aşana kadar, önce en son kullanılan kaynaktaki tüm site verilerini, ardından bir sonraki kaynaktaki tüm verileri temizler.
  • Safari daha önce verileri çıkarmadı ancak kısa süre önce tüm yazılabilir depolama alanlarına yeni bir yedi günlük sınır getirdi (aşağıya bakın).

iOS ve iPadOS 13.4 ile Safari 13.1'de macOS'te, IndexedDB, hizmet çalışanı kaydı ve Cache API dahil olmak üzere tüm komut dosyası yazılabilir depolama alanlarında yedi günlük bir sınır vardır. Bu, kullanıcı siteyle etkileşime geçmezse Safari'nin, Safari'nin kullanıldığı yedi gün sonra tüm içeriği önbellekten kaldıracağı anlamına gelir. Bu kaldırma politikası, ana ekrana eklenen yüklü PWA'lar için geçerli değildir. Ayrıntılı bilgi için WebKit blogundaki Üçüncü Taraf Çerezlerinin Tamamen Engellenmesi ve Daha Fazlası başlıklı makaleyi inceleyin.

Depolama paketleri

Storage Buckets API'nin temel amacı, sitelere birden fazla depolama paketi oluşturma olanağı vermektir. Bu paketlerde, tarayıcının her paketi diğer paketlerden bağımsız olarak silmeyi seçebilir. Bu sayede geliştiriciler, en değerli verilerin silinmediğinden emin olmak için çıkarma önceliğini belirtebilir.

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

IndexedDB, kullanılmadan önce önemli bir kurulum gerektiren düşük düzey bir API'dir. Bu, özellikle düşük karmaşıklıktaki verileri depolamak için can sıkıcı olabilir. Çoğu modern vaat tabanlı API'nin aksine etkinliğe dayalıdır. IndexedDB için idb gibi sarmalayıcılar, güçlü özelliklerin bir kısmını gizler.Daha da önemlisi, IndexedDB kitaplığıyla birlikte gelen karmaşık makineleri (ö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'a dayalı Web SQL'in yerine yenisini sunmak için popüler SQLite veritabanının yöneticileriyle birlikte çalıştı. Nasıl kullanacağınızla ilgili ayrıntılı bilgi için Kaynak Gizli Dosya Sistemi tarafından desteklenen tarayıcıda SQLite Wasm başlıklı makaleyi okuyun.

Sonuç

Sınırlı depolama alanı ve kullanıcıdan daha fazla veri depolaması istemenin sona erdiği günler geldi. Siteler, çalışması için ihtiyaç duydukları tüm kaynakları ve verileri etkili bir şekilde saklayabilir. StorageManager API'yi kullanarak ne kadar depolama alanı kullanabileceğinizi ve ne kadar depolama alanı kullandığınızı belirleyebilirsiniz. Kalıcı depolama ile, kullanıcı kaldırmadığı sürece verileri kaldırmaya karşı koruyabilirsiniz.

Ek kaynaklar

Teşekkürler

Bu kılavuzu inceleyen Jarryd Goodman, Phil Walton, Eiji Kitamura, Daniel Murphy, Darwin Huang, Josh Bell, Marijn Kruisselbrink ve Victor Costan'a özel teşekkürler. Bu metnin dayandığı orijinal makaleleri yazan Eiji Kitamura, Addy Osmani ve Marc Cohen'e teşekkürler. Eiji, mevcut davranışın doğrulanmasında faydalı olan Tarayıcı Depolama Alanı Kötüye Kullanımı adlı yararlı bir araç yazdı. Bu sayede mümkün olduğunca fazla veri depolayabilir ve tarayıcınızda depolama alanı sınırlarını görebilirsiniz. Safari'nin depolama alanı sınırlarını belirlemek için derinlemesine inceleme yapan François Beaufort'a ve orijinal gizli dosya sistemi, depolama alanı paketleri, SQLite Wasm ve 2024'te yapılacak genel içerik güncellemesi hakkında bilgi ekleyen Thomas Steiner'e teşekkür ederiz.

Lokomotif resim, Guillaume Bolduc tarafından Unsplash'te çekilmiştir.