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('没查到')
}
}
}
步骤
-
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(); -
更改查询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);