javascriptindexeddbdexie

Dexie JS: very large IndexedDB but empty tables


I have an application that uses vanilla javascript to show an openlayers map, people tap on a location and can add pictures. I'm using Dexie JS to store the data between pages until the user is ready to send everything. After everyting is uploaded, the record is deleted.

But Edge and Chrome keep chrashing on desktop and on mobile device. And it seems to have something to do with IndexedDB being to big.

There is a "main" record that holds details and a "related" table that holds the images.

To add a record, this is my code:

export const AddRecord = async (tablename, data) => {
let table = db.table(tablename);
let added = await table.add(data);
return added;
}

To delete a record, this is my code:

export const DeleteRecord = async (tablename, id) => {
let table = db.table(tablename);
let deleted = await table.delete(id);
return deleted;
}

But this isn't really the problem. Everything is executed and after uploading, records are deleted. But indexeddb keeps taking up space

I cleared all data and started with this

screenshot before

I added 1 record containing an id and three fields

screenshot one record

Storage is already up by 3MB which seems a lot for just one record. But that doesn't really matter because everything gets deleted anyway

screenshot storage with one record

But after uploading 25 images (with a size between 1.5MB and 2.5MB, i get this result

screenshot after

The tables i used to store the data is empty. What is taking up the space? Do i need to "purge" to completly delete all left over data?


Solution

  • What you describe seems similar to what happens when large ArrayBuffers are being indexed - see https://dexie.org/docs/Version/Version.stores()#warning

    By your description I don't see how you are indexing the tables, but if this is the case, the solution is to not index large ArrayBuffers or Uint8Arrays etc. Index only the fields that you are going to use in your where queries - other properties can be added without being indexed.

    For example, let's say you have declared your Dexie like so:

    const db = new Dexie('myDB');
    db.version(1).stores({
      imageEntries: '++id,image'
    });
    

    Then if you let add the image as so:

    const img = new UInt8Array(size);
    db.imageEntries.add({image: img});
    

    ...then this will make the database have to create lots of data for the "image" index along with the image data.

    The correct way of indexing the related table is more like:

    const db = new Dexie('myDB');
    db.version(2).stores({
      imageEntries: '++id' // Only the primary key here.
    });
    

    Remember, dexie does not enforce you to list all properties in version().stores(), but just the ones that you need to query on.