Indexeddb 缓慢检索问题

Indexeddb slow retrieval issue

你好,在我的应用程序中,目前(仍在开发中)一个索引数据库在一个集合中有 400 条记录。

索引是:id、vendor、price、model和subCategoryID。

这是一个记录示例:

{
 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 和 alphamap 是用于 threejs 目的的 base64 图像字符串)。

我正在实现一个用于产品过滤的用户界面,如果我想从集合中检索具有特定 "subCategoryID" 的所有产品,我使用以下方法完成此操作:

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 );
        }

    };

};

然而,我在测试我的方法后发现它非常慢...... console.TimeEnd() 在我的控制台中输出:getSubCategoryProducts: 11759.143ms

我相信12秒真的很慢。 是否有我遗漏的东西或我在这里做错了什么,或者是因为每个对象都有 base64 图像字符串?即便如此12秒我想也是不可接受的。

如果我的方法有问题或有任何改进的余地,请告诉我。

更新

经过深思熟虑后,我添加了一个范围,从而带来了改进。现在的要求 需要 3 秒,但看起来仍然很慢。

这是新方法:

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 );
        }

    };

};

您遇到的问题是将文件存储在数据库中,这肯定会降低 Indexeddb 性能,尤其是在移动设备上。

这个有两种不同的解决方案,我能想到的:

  • 一种是传统的从 table 中删除图像数据(productTexturealphaMap),并将它们存储在磁盘上的某个位置,并只在数据库中保留指向它的链接.
  • 第二种解决方案是将图像中的其余数据分成两个 table。将 productTexturealphaMap 存储在与其余数据分开的 table 中。然后获取类别中产品的查询将执行得非常快,显示占位符以便用户感觉应用程序上有东西在移动,然后向存储图像并将它们显示为 table 发出多个请求他们加载。