2

Hello in my app I have at the moment (still under development) an indexed-db with 400 records in a single collection.

The indexes are: id, vendor, price, model and subCategoryID.

Here is a sample of a record:

{
 id: 199,
 bundles: [235,548,983,918],
 categoryID:0 ,
 subCategoryID: 7,
 imageUrl : "/mock/mobiles/Alcatel-One-Touch-Pop-S7.png"
 model: "One Touch pop S7"
 vendor: "Alcatel",
 price: [213.4],
 tag:[],
 productTexture: "data:image/png;base64,iVBORw......",
 alphaMap: "data:image/jpeg;base64,/9j/4AAQSk...."
}

(productTexture and alphamap are base64 image string for threejs purposes).

I'm implementing a user interface for product filtering were I'd like to retrieve all the products from the collection with a specific "subCategoryID" and I accomplish that with the following method:

Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {

    console.time( "getSubCategoryProducts" );
    var results = [];
    var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
    var store = transaction.objectStore( this.config.collection );
    var index = store.index( "subCategoryID" );

    index.openCursor().onsuccess = function ( evt ) {

        var cursor = evt.target.result;

        if ( cursor ) {

            if ( cursor.value.subCategoryID === subCategoryID ) {
                results.push( cursor.value );
            }

            cursor.continue();

        } else {
            console.timeEnd( "getSubCategoryProducts" );
            callback( results );
        }

    };

};

However what I observed after I tested my method is that it is terribly slow... console.TimeEnd() output in my console: getSubCategoryProducts: 11759.143ms

I believe 12 seconds is really slow. Is there something I'm missing or anything that I'm doing wrong here or is it because of the base64 image strings that each object has? Even so 12 seconds is not acceptable I suppose.

Please let me know if there is something wrong in my approach or if there is any room for improvement.

UPDATE

After some thought I added a range which lead to an improvement. The request now takes 3 secs but still seems slow.

Here is the new method:

Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {

    console.time( "getSubCategoryProducts" );
    var results = [];
    var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
    var store = transaction.objectStore( this.config.collection );
    var boundKeyRange = IDBKeyRange.only( subCategoryID );
    var index = store.index( "subCategoryID" );

    index.openCursor( boundKeyRange ).onsuccess = function ( evt ) {

        var cursor = evt.target.result;

        if ( cursor ) {

            results.push( cursor.value );
            cursor.continue();

        } else {
            console.timeEnd( "getSubCategoryProducts" );
            callback( results );
        }

    };

};

1 Answer 1

1

the problem that you are having is storing files inside a database and that would definitely slow down Indexeddb performance, especially on mobile.

There are two different solutions for this, which I can think of:

  • One would be the traditional remove the image data (productTexture and alphaMap) from the table, and store them somewhere on disk and just keep links to it in the database.
  • And the second solution is to separate the rest of the data from the images into two tables. Store productTexture and alphaMap in a separate table than the rest of the data. And then the query for getting the products in a category will execute really fast, show placeholders so the user feels that something is moving on the app, and then fire multiple request towards the table which stores the images and display them as they load.
3
  • Hi Deni, May I know exactly what is the reason that there is delay in retrieving the data? I am also facing the same issue... Any links or documentation available for the same Commented May 11, 2020 at 6:52
  • Hey @DeekshaMulgaonkar the issue syd619 was facing is data model that has both data and metadata into one object, which slows down the speed of the application. Best solution for this is to store the data(images, payload) into a separate object that won't be queried when you search metadata. Commented May 11, 2020 at 20:38
  • 1
    Hi Deni, Thank you :) Commented May 12, 2020 at 4:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.