
無緩存下首屏加載120s

indexDB客戶端存儲數據后模型一步到位
參考資料
問題背景
一年前首次通過修改Cesium源碼中Resource相關代碼,實現(xiàn)了localforage緩存3dtiles瓦片,優(yōu)化了體積較大的三維瓦片資源加載效率。

實現(xiàn)邏輯
最近由于升級Cesium以便支持I3S模型加載,需要重新在不修改Cesium源碼的前提下重新實現(xiàn)上述優(yōu)化。
實現(xiàn)思路
- 嘗試從
Cesium3DTileset中查找資源請求相關事件,確認cesium采用XHR請求資源。 - 查找一些重寫
XHR的方法,發(fā)現(xiàn)一般都對其他資源正常加載有影響。 - 找到
ajax-hook庫,實現(xiàn)了上圖功能邏輯。ajax-hook庫提供了一種方式來攔截和重寫XHR請求,從而實現(xiàn)對請求的控制和修改。使用ajax-hook,我們可以在請求發(fā)送之前或響應返回之后對XHR對象進行處理。這使得我們可以在Cesium中使用ajax-hook庫來攔截和修改3D Tiles資源請求,以滿足我們的定制需求。
需要注意的是,在使用ajax-hook庫進行XHR重寫時,我們應該謹慎處理,以避免對整個應用程序的網絡請求產生意外的影響。確保我們只攔截和修改與3D Tiles資源加載相關的請求,并在處理完請求后恢復正常的XHR行為。這樣可以確保我們的功能邏輯與其他資源加載不會發(fā)生沖突,并保持應用程序的穩(wěn)定性和性能。
代碼
// 初始化localstorage
const store = localforage.createInstance({
name: "MyDB",
});
const storeUrls = [];
storeUrls.push(
"../gisserver/3DTiles/3DModel/tileset.json?t=1"
);
// proxy請求攔截
unProxy();
proxy({
onRequest: async (config, handler) => {
const { url } = config;
const needDB = storeUrls.reduce((pre, curr) => {
const path = curr.substring(0, curr.lastIndexOf("/") + 1);
return pre || url.includes(path);
}, false);
if (needDB) {
if (window.localStorage.getItem(url) === "1") {
const data = await store.getItem(url);
if (data) {
handler.resolve({
config,
status: 200,
// headers,
response: data,
});
return;
}
}
}
handler.next(config);
},
onResponse: (response, handler) => {
const {
config: { url },
} = response;
const needDB = storeUrls.reduce((pre, curr) => {
const path = curr.substring(0, curr.lastIndexOf("/") + 1);
return pre || url.includes(path);
}, false);
if (needDB) {
store
.setItem(url, response.response)
.then(window.localStorage.setItem(url, "1")); // Set a flag in local storage to indicate that the data is stored
}
handler.next(response);
},
});