Three.js模型indexdb缓存2进制文件,加载优化

3,832 阅读2分钟

Three.js模型indexdb缓存,加载优化

模型很大,每次都重新请求,耗费内存,请求耗时长,造成资源浪费,以gltf/glb模型举例

  • 创建indexDB

    var connect = window.indexedDB.open('hiwebpage');
        var db
        connect.onupgradeneeded = function (event) {
          console.log("数据库更新")
          db = event.target.result;
          // 判断是否有这个表
          if (!db.objectStoreNames.contains('person')) {
            // 创建表
            var objectStore;
            objectStore = db.createObjectStore('person', {
              // 主键
              keyPath: 'id'
            });
            // 创建索引
            objectStore.createIndex('blob', 'blob', {
              // 是否唯一
              unique: false
            });
            objectStore.createIndex('name', 'name', {
              // 是否唯一
              unique: true
            });
          }
        }
        connect.onsuccess = function (event) {
          console.log("数据库打开成功")
          db = event.target.result
    
        };
    
  • indexDB新增

function addData(storename, data, callback) {
      let store = db.transaction(storename, 'readwrite').objectStore(storename);
      let request = store.add(data);
      request.onerror = function () {
        console.error('add添加数据库中已有该数据')
      };
      request.onsuccess = function () {
        console.log('add添加数据已存入数据库')
        callback();
      };
    }
  • indexDB查找
 function find(storename, key, callback) {
      let store = db.transaction(storename, 'readwrite').objectStore(storename);
      let request = store.get(key);
      request.onerror = function () {
        console.error('getDataByKey error');
      };
      request.onsuccess = function (e) {
        let result = e.target.result;
        console.log(result);
        if(result) {
           console.log('查找数据成功')
        }else {
          console.log('没查到')
        }
       
      }

    }

步骤

  1. xhr请求模型并添加indexdb

    var xhr = new XMLHttpRequest(),
          blob;
    
        xhr.open("GET", "./models/park/park.gltf", true);
        xhr.responseType = "blob";
        xhr.addEventListener("load", function () {
          if (xhr.status === 200) {
            console.log("ok");
            blob = xhr.response;
              // 请求成功之后存入indexdb
            addData('person', {
              id: 'xy',
              blob: blob
            }, () => {
              console.log('添加成功-开始查询')
                // 存完之后查询
              find('person', 'xy', () => {
                console.log('查找结束')
              })
            })
         
          }
        }, false);
        // Send XHR
         xhr.send();
    
  2. 更改查询indexdb的函数并渲染(这里有使用压缩gltf和解压路径的操作)

     function find(storename, key, callback) {
          let store = db.transaction(storename, 'readwrite').objectStore(storename);
          let request = store.get(key);
          request.onerror = function () {
            console.error('getDataByKey error');
          };
          request.onsuccess = function (e) {
            let result = e.target.result;
            console.log('查找数据成功')
            console.log(result);
            if(result) {
               var url = URL.createObjectURL(result.blob)
              // let loader = new THREE.GLTFLoader();
              THREE.DRACOLoader.setDecoderPath('three/examples/js/libs/draco/gltf/'); //设置解压库文件路径
              var dracoLoader = new THREE.DRACOLoader();
              gltfloader.setDRACOLoader(dracoLoader);
              gltfloader.load(url, function (gltf) {
                // 清理 blob协议缓存
                // URL.revokeObjectURL(url)
                scene.add(gltf.scene)
                renderDailog();
                gltf.scene.position.set(0, 0, 0);
                if (callback) {
                  callback(result);
                }
              });
            }else {
              console.log('没查到')
              // 没查到再此请求并存入 indexDB
              xhr.send();
            }
           
          }
    
        }
    

    完整代码

    var connect = window.indexedDB.open('hiwebpage');
    
    
        var db
    
    
        connect.onupgradeneeded = function (event) {
          console.log("数据库更新")
    
    
          db = event.target.result;
          // 判断是否有这个表
          if (!db.objectStoreNames.contains('person')) {
            // 创建表
            var objectStore;
            objectStore = db.createObjectStore('person', {
              // 主键
              keyPath: 'id'
            });
            // 创建索引
            objectStore.createIndex('blob', 'blob', {
              // 是否唯一
              unique: false
            });
            objectStore.createIndex('name', 'name', {
              // 是否唯一
              unique: true
            });
          }
        }
    
        connect.onsuccess = function (event) {
          console.log("数据库打开成功")
          db = event.target.result
          find('person', 'xy', () => {
            console.log('查找结束')
          })
    
        };
    
        function addData(storename, data, callback) {
          let store = db.transaction(storename, 'readwrite').objectStore(storename);
          let request = store.add(data);
          request.onerror = function () {
            console.error('add添加数据库中已有该数据')
          };
          request.onsuccess = function () {
            console.log('add添加数据已存入数据库')
            callback();
          };
        }
    
        function find(storename, key, callback) {
          let store = db.transaction(storename, 'readwrite').objectStore(storename);
          let request = store.get(key);
          request.onerror = function () {
            console.error('getDataByKey error');
          };
          request.onsuccess = function (e) {
            let result = e.target.result;
            console.log('查找数据成功')
            console.log(result);
            if(result) {
               var url = URL.createObjectURL(result.blob)
              // let loader = new THREE.GLTFLoader();
              THREE.DRACOLoader.setDecoderPath('three/examples/js/libs/draco/gltf/'); //设置解压库文件路径
              var dracoLoader = new THREE.DRACOLoader();
              gltfloader.setDRACOLoader(dracoLoader);
              gltfloader.load(url, function (gltf) {
                // 清理 blob协议缓存
                // URL.revokeObjectURL(url)
                scene.add(gltf.scene)
                renderDailog();
                gltf.scene.position.set(0, 0, 0);
                if (callback) {
                  callback(result);
                }
              });
            }else {
              console.log('没查到')
              xhr.send();
            }
           
          }
    
        }
    
        var xhr = new XMLHttpRequest(),
          blob;
    
        xhr.open("GET", "./models/park/park.gltf", true);
        // Set the responseType to blob
        xhr.responseType = "blob";
    
        xhr.addEventListener("load", function () {
          if (xhr.status === 200) {
            console.log("ok");
    
            // File as response
            blob = xhr.response;
            addData('person', {
              id: 'xy',
              blob: blob
            }, () => {
              console.log('添加成功-开始查询')
              find('person', 'xy', () => {
                console.log('查找结束')
              })
            })
            // Put the received blob into IndexedDB
            // putElephantInDb(blob);
          }
        }, false);