IndexedDB
I found this article helpful to get me started: Working with IndexedDB | Articles | web.dev. It recommends the jakearchibald/idb: IndexedDB, but with promises library, which I found intuitive to work with.
- Using IndexedDB - Web APIs | MDN
- Should have one object store for each type of data
- eg. when storing
person
s andnotes
, it should have an object store for eeach - these stores can be set when creating the database via
upgrade
- you’re only allowed to do it then for database integrity
- eg. when storing
Create Object store
Keys:
- You can pass in a key that is unique as you create the “table”
- or you can set this which will automatically generate a key
db.createObjectStore('notes', { autoIncrement: true });
this sets the primary key automatically to an incrementing number
db.createObjectStore('logs', { keyPath: 'id', autoIncrement: true });
this is similar, but explicitly set id
as the identifier field that is filled with incrementing numbers
Indexing
const objectStore = db.createObjectStore('storeName');
objectStore.createIndex('indexName', 'property', options);
unique: true
the index doesn’t allow duplicates for this fieldmultiEntry
determines how to deal with arraystrue
: add index for each element- otherwise: add single entry containing the array
Best practices
Best Practices for Using IndexedDB | Articles | web.dev:
Store files as ArrayBuffer
Safari on iOS cannot store Blobs in IndexedDB.
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);
});
}
Don’t store large, nested objects as a single record
The reason is because when IndexedDB stores an object, it must first create a structured clone of that object, and the structured cloning process happens on the main thread. The larger the object, the longer the blocking time will be.