IndexedDB vs localStorage: welke browseropslag gebruikt u?
IndexedDB vs localStorage
IndexedDB vs localStorage: limieten, snelheid, wanneer welke | We.Inc
Vergelijk IndexedDB en localStorage naast elkaar: opslaglimieten per browser, sync of async, wat elk kan opslaan, plus een live demo die één notitie in beide bewaart.
Kies localStorage voor een paar kleine instellingen: het slaat alleen strings op, ongeveer 5 MiB per origin, en elke aanroep blokkeert de pagina tot hij klaar is. Kies IndexedDB voor echte data: het is asynchroon, werkt met transacties, slaat objecten, datums en bestanden op, en de quota is een deel van de schijf. De demo hieronder schrijft één notitie naar beide.
De korte versie
Vraag
localStorage
IndexedDB
Wat kan erin?
Alleen strings
Alles wat het structured clone-algoritme kopieert, inclusief Blob en File
Grootte
Tot 5 MiB per origin
Een deel van de vrije schijfruimte, per browser bepaald
Blokkeert het de pagina?
Ja, elke aanroep is synchroon
Nee, resultaten komen binnen via events of promises
Transacties en indexen
Nee
Ja
Bruikbaar in een Web Worker
Nee, het is een eigenschap van window
Ja
Het meest geschikt voor
Thema, laatste tabblad, een conceptstring
Offline data, caches, bestanden, alles wat u doorzoekt
Beide API's bewaren data in de browser van de bezoeker nadat het tabblad is gesloten, en beide zijn gebonden aan de origin van de pagina. Het verschil zit in het gewicht. localStorage is een piepkleine synchrone stringmap die u in een minuut leert; IndexedDB is een kleine database met versies, object stores en transacties. Deze pagina toont de echte limieten uit de documentatie en laat u zien wat elk van beide teruggeeft.
Typ een notitie en druk op Opslaan in beide. De pagina schrijft hem naar localStorage als JSON-tekst en naar een IndexedDB object store als echt object.
Druk op Teruglezen. Het resultaatpaneel toont het type dat elke API teruggaf: een string uit localStorage, een object met een werkende Date uit IndexedDB.
Druk op Quota controleren om navigator.storage.estimate() te vragen hoeveel deze origin gebruikt en mag gebruiken. De getallen zijn schattingen.
Druk op Demodata wissen om de demosleutel te verwijderen en de demodatabase te wissen. Niets verlaat uw apparaat.
Zet localStorage.setItem in een try...catch. Een volle opslag gooit QuotaExceededError, en sommige privacyinstellingen gooien SecurityError bij de eerste toegang.
Sla de uitvoer van JSON.stringify op in localStorage en parse die bij het lezen. Datums komen terug als strings, dus zet ze zelf om.
Voor IndexedDB zet een kleine wrapper zoals idb of Dexie de stijl met requests en events om in promises en bespaart u veel boilerplate.
Roep navigator.storage.persist() alleen aan voor data waarvan het verlies iemand echt zou raken, zoals offline documenten. Anders kan de browser het verwijderen als de opslag krap wordt.
Bewaar nooit geheimen of sessietokens in een van beide opslagen. Elk script dat op de pagina draait, kan ze lezen.
Veelgestelde vragen
Hoeveel kan localStorage bevatten?
MDN documenteert een limiet van 5 MiB local storage en 5 MiB session storage per origin, 10 MiB in totaal. Omdat waarden UTF-16-strings zijn, kan het aantal tekens dat erin past lager zijn dan u verwacht. Wie over de limiet gaat, krijgt een QuotaExceededError.
Hoeveel kan IndexedDB bevatten?
Dat hangt af van de browser en de schijf. Chromium-browsers geven een origin tot 60% van de totale schijfgrootte. Firefox staat in best-effort-modus het kleinste toe van 10% van de schijf of 10 GiB per sitegroep. Safari-browserapps staan ongeveer 60% van de schijf toe. Gebruik navigator.storage.estimate() om het echte getal uit te lezen.
Is IndexedDB sneller dan localStorage?
Voor één piepkleine waarde is localStorage meestal sneller in code te schrijven en snel genoeg in gebruik. Het probleem is dat het synchroon is, dus grote lees- en schrijfacties bevriezen de main thread. IndexedDB doet het werk buiten de hoofdstroom en laat weten wanneer het klaar is, zodat scrollen en typen soepel blijven.
Kan de browser mijn IndexedDB-data verwijderen?
Ja. Opslag is standaard best-effort, dus de browser kan de data van een origin verwijderen als de schijf krap wordt. Met navigator.storage.persist() schakelt u over naar persistente modus, waarin alleen de gebruiker het kan wissen. Firefox toont een toestemmingsvraag; Chrome en Safari beslissen op basis van hoe iemand de site gebruikt.
Moet ik localStorage gebruiken voor een inlogtoken?
Nee. Elk script op de pagina, ook een geïnjecteerd script, kan localStorage en IndexedDB lezen. Bewaar sessie-ID's in cookies met HttpOnly, Secure en SameSite, die paginascripts niet kunnen lezen.
Waarom synchroon ertoe doet
Als code localStorage.getItem aanroept, stopt de browser met het uitvoeren van ander JavaScript tot de waarde terugkomt van de schijf. Bij een themanaam merkt niemand dat. Bij een paar megabyte JSON die bij elke paginalading wordt geparsed, ziet u een pauze voordat de pagina op tikken reageert.
IndexedDB geeft meteen een request-object terug en vuurt later success of error af. Die vorm vraagt meer code, en daarom gebruiken de meeste projecten een promise-wrapper, maar hij houdt de pagina nooit gegijzeld.
Strings tegenover structured clone
localStorage maakt van alles tekst. Sla het getal 3 op en u leest de string "3" terug; sla een object op zonder JSON.stringify en u leest "[object Object]" terug.
IndexedDB kopieert waarden met het structured clone-algoritme, dus een Date blijft een Date, een Map blijft een Map, en een Blob of File kan worden opgeslagen zoals hij is. Daardoor is het geschikt voor offline afbeeldingen, opgenomen audio of concepten met bijlagen.
Een eenvoudige regel om te kiezen
Als de data op één korte regel past en u die één keer bij het opstarten leest, is localStorage prima. Als u erin wilt zoeken, tellen of bladeren, er binaire bestanden in wilt opslaan of het vanuit een service worker wilt bijwerken, gebruik dan IndexedDB.
Serverdata is een derde optie die vaak beter is dan beide: als iemand verwacht hetzelfde te zien op een ander apparaat, hoort het in uw database, met de browseropslag alleen als cache.
Opslaglimieten per browser
Cijfers zoals gedocumenteerd op de pagina over opslagquota van MDN. IndexedDB, de Cache API en het origin private file system delen dezelfde quota.
Quota per origin
Browser
localStorage
IndexedDB (best-effort)
IndexedDB (persistent)
Chrome, Edge en andere Chromium-browsers
5 MiB
Tot 60% van de totale schijf
Tot 60% van de totale schijf
Firefox
5 MiB
Het kleinste van 10% van de schijf of 10 GiB per sitegroep
Tot 50% van de schijf, met een maximum van 8 TiB
Safari-browserapp
5 MiB
Ongeveer 60% van de totale schijf
Ongeveer 60% van de totale schijf
Apps die webinhoud insluiten (WebKit)
5 MiB
Ongeveer 15% van de totale schijf
Ongeveer 15% van de totale schijf
Dezelfde opslag in beide API's
localStorage: stringify, afvangen, parse
De try...catch vangt een volle of geblokkeerde opslag af. De datum moet na het parsen met de hand opnieuw worden opgebouwd.
IndexedDB: openen, upgraden, schrijven in een transactie
onupgradeneeded draait de eerste keer en telkens als het versienummer omhooggaat; dat is de enige plek om object stores aan te maken.
Vraag hoeveel ruimte u hebt, en vraag om die te behouden
estimate() geeft bij benadering het aantal bytes terug. persist() resolvet naar true als de browser persistente opslag heeft toegekend.
Sla één notitie op in beide opslagen
Deze demo draait alleen in uw browser. Hij schrijft onder de sleutel we-demo-note en in een database met de naam we-demo-db, en de knop Wissen verwijdert beide.
Notitie om op te slaan
Vrijdag de drukker bellen
Opslaan in beide
Teruglezen
Quota controleren
Demodata wissen
Nog niets gelezen. Sla een notitie op en druk dan op Teruglezen.
localStorage gaf terug
IndexedDB gaf terug
Type: {v}
savedAt is een Date: {v}
Niets opgeslagen
De notitie is opgeslagen in localStorage en IndexedDB.
Demosleutel en database verwijderd.
Deze origin gebruikt ongeveer {n} MB van de circa {v} MB beschikbaar.
Deze browser biedt navigator.storage.estimate() niet aan.