ajax-hook+indexDB+Cesium優(yōu)化三維資源加載

無緩存下首屏加載120s

indexDB客戶端存儲數據后模型一步到位

參考資料

Ajax-hook原理解析
localforage中文文檔

問題背景

一年前首次通過修改Cesium源碼中Resource相關代碼,實現(xiàn)了localforage緩存3dtiles瓦片,優(yōu)化了體積較大的三維瓦片資源加載效率。


實現(xiàn)邏輯

最近由于升級Cesium以便支持I3S模型加載,需要重新在不修改Cesium源碼的前提下重新實現(xiàn)上述優(yōu)化。

實現(xiàn)思路

  1. 嘗試從Cesium3DTileset中查找資源請求相關事件,確認cesium采用XHR請求資源。
  2. 查找一些重寫XHR的方法,發(fā)現(xiàn)一般都對其他資源正常加載有影響。
  3. 找到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);
        },
      });
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容