Tarayıcıda veri depolamak için birçok farklı seçenek vardır. İhtiyaçlarınıza en uygunu hangisi?
İnternet bağlantıları hareket halindeyken kesintili olabilir veya hiç olmayabilir. Bu nedenle, çevrimdışı destek ve güvenilir performans, progresif web uygulamalarında yaygın ö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 hangisi? Ne kadar saklayabilirsiniz? Kiracının tahliye edilmesini nasıl önlersiniz?
Hangisini kullanmalıyım?
Kaynakları depolamaya yönelik genel önerimiz:
- Uygulamanızı yüklemek için gerekli ağ kaynakları için Cache Storage API'yi (hizmet çalışanlarının bir parçası) kullanın.
- Dosya tabanlı içerikler için Kaynak Özel Dosya Sistemi'ni (OPFS) kullanın.
- Diğer veriler için IndexedDB'i (promises sarmalayıcısı ile) kullanın.
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 kullanılabilen başka depolama mekanizmaları da vardır ancak bunların kullanımı sınırlıdır ve önemli performans sorunlarına neden olabilir.
SessionStorage sekmeye özeldir ve sekmenin ömrü boyunca geçerlidir. IndexedDB anahtarı gibi oturuma özgü küçük miktarda bilgi depolamak için yararlı olabilir. Eşzamanlı olduğu ve ana iş parçacığını engellediğ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.
Çerezler faydalı olsa da depolama alanı olarak kullanılmamalıdır. Çerezler her HTTP isteğiyle birlikte gönderilir. Bu nedenle, az miktarda veri dışında bir şey 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 fazlası. Tarayıcı uygulamaları değişiklik gösterir ancak kullanılabilir depolama alanı 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"yi etkinleştirdiyse depolama alanı kotası, yaklaşık 300 MB'lık maksimum değere kadar önemli ölçüde azaltı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
vefoo.bar.example.com
) 2 GB'a kadar kullanabilir. Kalan depolama alanı miktarını belirlemek için StorageManager API'yi kullanabilirsiniz. - Safari (hem masaüstü hem de mobil) yaklaşık 1 GB'a izin veriyor. Sınıra ulaşıldığında Safari, kullanıcıdan izin isteyerek sınırı 200 MB'lık artışlarla artırır. 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ı kullanmasına izin vermesini ister, ardından 50 MB'lık artışlarla tekrar sorar.
Günümüzde çoğu modern tarayıcı kullanıcıdan izin istemez ve sitenin ayrılan kotasını kullanmasına izin verir. Bunun istisnası Safari'dir. Safari, depolama alanı kotası aşıldığında ayrılan kotayı artırma izni ister. Bir kaynak, kendisine ayrılan kotadan daha fazlasını kullanmaya çalışırsa veri yazmaya yönelik diğer girişimler başarısız olur.
Kullanılabilir depolama alanı miktarı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 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 uygulamalarınızın düşük disk kullanılabilirliği senaryolarındaki 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, mümkün olduğunca fazla depolama alanını hızlı bir şekilde kullanmayı denemek için bir basit araç yazdım. Bu, farklı depolama mekanizmalarını denemek ve kotanızın tamamını kullandığınızda ne olacağını görmek için hızlı bir yoldur.
Kotayı aşma sorununu nasıl çözebilirim?
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çerikleri silin, verileri boyuta göre kaldırın veya kullanıcıların silmek istediklerini seçebilecekleri bir yöntem sunun.
Hem IndexedDB hem de Cache API, mevcut kotayı aştığınızda QuotaExceededError
adlı bir DOMError
oluşturur.
IndexedDB
Kaynak kotasını aştıysa IndexedDB'e 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ı kontrol edildiğinde 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ş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 çalışır?
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.
- Kullanılabilir disk alanı dolduğunda Firefox, tarayıcı sınırı aşmadığı sürece önce en uzun süre kullanılmayan kaynaktaki tüm site verilerini, ardından bir sonraki kaynağı temizleyerek verileri kaldırmaya başlar.
- Safari daha önce verileri kaldırmazdı ancak kısa süre önce tüm yazılabilir depolama alanlarında yedi günlük yeni bir sınır uyguladı (aşağıya bakın).
iOS ve iPadOS 13.4'ten ve 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ında yedi günlük bir sınır uygulanmaktadı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 fikri, sitelere birden fazla depolama paketi oluşturma olanağı tanımaktır. Bu durumda tarayıcı, her paketi diğer paketlerden bağımsız olarak silebilir. Bu sayede geliştiriciler, en değerli verilerin silinmediğinden emin olmak için çıkarma önceliğini belirtebilir.
Bonus: IndexedDB için neden 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. Söze dayalı modern API'lerin çoğunun aksine, etkinlik tabanlı bir API'dir. IndexedDB için idb gibi Promise sarmalayıcılar, güçlü özelliklerin bazılarını gizler ancak daha da önemlisi, IndexedDB kitaplığıyla birlikte gelen karmaşık mekanizmayı (ör. işlemler, şema sürümlendirme) gizler.
Bonus: SQLite Wasm
Web SQL desteği sonlandırılıp Chrome'dan kaldırıldıktan sonra Google, popüler SQLite veritabanının koruyucularıyla birlikte çalışarak SQLite tabanlı bir Web SQL alternatifi sundu. Kullanımıyla ilgili ayrıntılar için Origin Private File System 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 makalenin temel aldığı orijinal makaleleri yazan Eiji Kitamura, Addy Osmani ve Marc Cohen'e teşekkürler. Eiji, mevcut davranışı doğrulamada faydalı olan Browser Storage Abuser adlı faydalı 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.
Hero resim, Unsplash'taki Guillaume Bolduc'a aittir.