欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript前端實(shí)現(xiàn)頁(yè)面白屏檢測(cè)與解決

 更新時(shí)間:2025年03月19日 16:27:05   作者:水煮白菜王  
白屏通常指的是頁(yè)面打開后,瀏覽器上面的地址欄已經(jīng)顯示完整的?URL,但是頁(yè)面內(nèi)容無法渲染,只有白色的空白頁(yè)面,下面我們就來看看白屏出現(xiàn)的具體原因與解決方法吧

白屏通常指的是頁(yè)面打開后,瀏覽器上面的地址欄已經(jīng)顯示完整的 URL,但是頁(yè)面內(nèi)容無法渲染,只有白色的空白頁(yè)面。
導(dǎo)致白屏的原因大致可分為兩類:

資源加載問題

代碼執(zhí)行錯(cuò)誤

從現(xiàn)代前端視角來看,這兩種原因都跟當(dāng)前SPA框架的廣泛使用有關(guān)。

資源加載問題

這里的資源特指 JavaScript 腳本、樣式表、圖片等靜態(tài)資源,不包括接口調(diào)用等動(dòng)態(tài)資源。

資源加載問題導(dǎo)致的白屏可以分為可恢復(fù)的和不可恢復(fù)的兩大類

1.可恢復(fù)的白屏

可恢復(fù)的白屏常見于第一次進(jìn)人頁(yè)面時(shí),由于資源加載過慢或者接口請(qǐng)求未返回,所以瀏覽器無法執(zhí)行下一步驟。

這種白屏通常是網(wǎng)絡(luò)狀況太差或者設(shè)備性能太差等原因?qū)е碌?,一般在瀏覽器返回后,就能恢復(fù)頁(yè)面渲染,可以通過監(jiān)控首屏?xí)r間來發(fā)現(xiàn)。

如果生產(chǎn)環(huán)境的首屏?xí)r間呈異常上升趨勢(shì),那么一定是頁(yè)面白屏?xí)r間過長(zhǎng)導(dǎo)致的,開發(fā)人員應(yīng)該及時(shí)關(guān)注并排查近期改動(dòng)的代碼

2.不可恢復(fù)的白屏

不可恢復(fù)的白屏大多是由于網(wǎng)絡(luò)或緩存問題導(dǎo)致的。

常見的例子莫過于 React、Vue 等 SPA 框架構(gòu)建的 Web 應(yīng)用,一旦 [bundle|app].js 因?yàn)榫W(wǎng)絡(luò)原因訪問失敗,便會(huì)引發(fā)頁(yè)面白屏。

你可以訪問任意SPA框架構(gòu)建的Web應(yīng)用,按照如下步驟復(fù)現(xiàn):打開 DevTools > Network,找到 app.xxx.js,右鍵并選中 Block request URL,隨后刷新頁(yè)面。

另一個(gè)例子是SPA項(xiàng)目打包后,在非首次線上替換dist文件時(shí),某些手機(jī)/瀏覽器在之后首次打開頁(yè)面,可能出現(xiàn)白屏情況

在用戶端會(huì)默認(rèn)緩存index.html入口文件,而由于vue打包生成的css/js都是哈希值,跟上次的文件名都不同,因此會(huì)出現(xiàn)找不到css/js的情況,導(dǎo)致白屏的產(chǎn)生。在服務(wù)端更新包之后,由于舊的文件被刪除,而index.html所鏈接的路徑依然是舊文件路徑,因此會(huì)找不到文件,從而白屏。

代碼執(zhí)行錯(cuò)誤

代碼執(zhí)行錯(cuò)誤導(dǎo)致的白屏一般伴隨著功能流程的阻斷出現(xiàn),并且很難通過等待或者頁(yè)面刷新等方法修復(fù)。
這類問題出現(xiàn)的原因通常是前端代碼邏輯錯(cuò)誤,或是后端接口的臟數(shù)據(jù)導(dǎo)致的前端數(shù)據(jù)解析邏輯錯(cuò)誤,最終導(dǎo)致運(yùn)行異常的前端代碼觸發(fā)了頁(yè)面崩潰。

例如,如果 React 中的組件發(fā)生了異常,并且外部沒有使用 componentDidCatch 或者getDerivedStateFromError 捕錯(cuò)誤,那么 React 組件 render 掛載的目標(biāo)節(jié)點(diǎn)下的 DOM 樹會(huì)被移除、頁(yè)面就會(huì)出現(xiàn)白屏。

自React 16 起,任何未被錯(cuò)誤邊界捕獲的錯(cuò)誤將會(huì)導(dǎo)致整個(gè) React 組件樹被卸載。

白屏檢測(cè)

檢測(cè)根節(jié)點(diǎn)是否渲染

這種方法的原理是在當(dāng)前主流 SPA 框架下,DOM 一般掛載在一個(gè)根節(jié)點(diǎn)之下(比如 < div id=“app” > ),發(fā)生白屏后通常是根節(jié)點(diǎn)下所有 DOM 被卸載。

我們可以通過在頁(yè)面渲染完成后,檢查頁(yè)面根節(jié)點(diǎn)的子元素是否存在,如果不存在,則可以判斷頁(yè)面是白屏狀態(tài)。

這種方案簡(jiǎn)潔明了,但缺點(diǎn)也很明顯,項(xiàng)目有骨架屏渲染的情況下無法判斷是否白屏。

如在 Vue.js 中可以使用鉤子函數(shù) mounted 或 created 在頁(yè)面渲染完成后進(jìn)行檢測(cè)。

export default {
  created() {
    // 獲取頁(yè)面根節(jié)點(diǎn)
    const rootNode = document.querySelector('#app');
    // 檢測(cè)根節(jié)點(diǎn)的子元素是否存在
    if (rootNode.children.length === 0) {
      // 頁(yè)面是白屏狀態(tài)
      console.error('頁(yè)面白屏了!');
    } else {
      // 頁(yè)面正常顯示
      console.log('頁(yè)面正常顯示');
    }
  },
}

由于 SPA 應(yīng)用通常使用異步加載方式加載組件和數(shù)據(jù),因此需要確保在頁(yè)面組件渲染完成后再進(jìn)行白屏檢測(cè)。如果在組件渲染之前進(jìn)行檢測(cè),可能會(huì)誤判為白屏。另外,SPA 應(yīng)用可能會(huì)存在某些異步請(qǐng)求失敗或加載超時(shí)等問題,也需要考慮這些因素對(duì)白屏檢測(cè)的影響。

Mutation Observer 監(jiān)聽 DOM 變化

Mutation Observer 是一種在 DOM 樹發(fā)生變化時(shí)進(jìn)行回調(diào)的方式,可以用于監(jiān)聽頁(yè)面元素的變化??梢酝ㄟ^ Mutation Observer 來監(jiān)聽 DOM 樹變化,從而判斷頁(yè)面是否白屏。

但這個(gè)方式的缺點(diǎn)也很明顯:

  • 對(duì)性能的影響:使用 Mutation Observer 監(jiān)聽 DOM 變化會(huì)對(duì)瀏覽器性能造成一定影響,尤其是當(dāng) DOM樹變化頻繁時(shí),會(huì)導(dǎo)致回調(diào)函數(shù)頻繁執(zhí)行,影響頁(yè)面的響應(yīng)速度和用戶體驗(yàn)。
  • 兼容性問題:Mutation Observer 的兼容性不是很好,不同瀏覽器支持程度不同,需要進(jìn)行兼容性處理。
  • 誤判問題:有些情況下,頁(yè)面并不是真正的白屏,但是 Mutation Observer 仍然會(huì)誤判為白屏,例如頁(yè)面中有一個(gè)空白的 div元素占位,此時(shí)即使頁(yè)面內(nèi)容未加載,也不會(huì)被判定為白屏狀態(tài)。

具體實(shí)現(xiàn)步驟如下:

創(chuàng)建一個(gè) Mutation Observer 實(shí)例,并指定回調(diào)函數(shù)。

const observer = new MutationObserver((mutations) => {
  // mutations 表示 DOM 樹的變化列表
});

將 Mutation Observer 實(shí)例與根節(jié)點(diǎn)進(jìn)行綁定,并指定監(jiān)測(cè)的選項(xiàng)。

const rootNode = document.documentElement;
const observerConfig = {
  childList: true, // 監(jiān)聽子節(jié)點(diǎn)的變化
  subtree: true, // 監(jiān)聽所有后代節(jié)點(diǎn)的變化
  attributes: true, // 監(jiān)聽節(jié)點(diǎn)屬性的變化
  characterData: true, // 監(jiān)聽節(jié)點(diǎn)文本內(nèi)容的變化
  attributeOldValue: true, // 記錄節(jié)點(diǎn)屬性變化前的值
  characterDataOldValue: true, // 記錄節(jié)點(diǎn)文本內(nèi)容變化前的值
};
observer.observe(rootNode, observerConfig);

在回調(diào)函數(shù)中檢查 DOM 樹的變化,如果發(fā)現(xiàn)根節(jié)點(diǎn)的子元素存在,則可以判斷頁(yè)面不是白屏狀態(tài)。

const observer = new MutationObserver((mutations) => {
  // 檢查根節(jié)點(diǎn)的子元素是否存在
  if (rootNode.children.length > 0) {
    console.log('頁(yè)面正常顯示');
  } else {
    console.error('頁(yè)面白屏了!');
  }
});

頁(yè)面截圖

通過對(duì)網(wǎng)頁(yè)進(jìn)行截圖,對(duì)截圖進(jìn)行像素點(diǎn)分析,判斷頁(yè)面是否白屏。一般情況下,可以統(tǒng)計(jì)截圖中所有像素點(diǎn)的 RGB 值,如果所有像素點(diǎn)的 RGB 值都相同,且與白色(RGB(255, 255, 255))非常接近,那么就可以判斷頁(yè)面是白屏狀態(tài)。

這個(gè)方式的缺點(diǎn)如下:

頁(yè)面截圖需要包含足夠的像素點(diǎn),以便能夠準(zhǔn)確地檢測(cè)頁(yè)面是否白屏。如果截圖不夠清晰,可能會(huì)導(dǎo)致誤判。

有些情況下,頁(yè)面并不是真正的白屏,但是由于一些外部原因(例如網(wǎng)絡(luò)問題)導(dǎo)致頁(yè)面未加載,此時(shí)頁(yè)面截圖也會(huì)被判定為白屏狀態(tài)。

頁(yè)面存在骨架屏的情況下,需要對(duì)比骨架屏

解決辦法

思路:減小打包后的體積(sourceMap關(guān)掉,CDN引入, 路由懶加載,組件按需加載)

  • 提高渲染速度
  • 優(yōu)化用戶體驗(yàn)
  • CDN資源優(yōu)化

將依賴的第三方npm包全部改為通過CDN鏈接獲取,在index.html里插入相應(yīng)鏈接

<body>
  <div id="app"></div>
  <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
  <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
  <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
  <script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
</body>

在vue.config.js里配置externals屬性

module.exports = {
 ···
    externals: {
      'vue': 'Vue',
      'vuex': 'Vuex',
      'vue-router': 'VueRouter',
      'axios':'axios',
      'element-ui': 'ElementUI'
    }
 }

卸載相關(guān)依賴的npm包

npm uninstall xxx

使用gzip壓縮

前端處理:

// npm i compression-webpack-plugin -S
const CompressionPlugin = require('compression-webpack-plugin');

???????module.exports = {
  productionSourceMap: false,
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      return {
        plugins: [
          new CompressionPlugin({
            // 匹配規(guī)格
            test: /\.js$|\.html$|\.css$|\.png$/,
            // 文件超過多大進(jìn)行壓縮 單位Byte
            threshold: 10240,
            // 是否刪除源文件(建議不刪除)
            deleteOriginalAssets: false
          })
        ],
      }
    }
  },
}

還需要在 nginx開啟gzip壓縮, 例如:

 gzip on;
 gzip_static on; //當(dāng)存在.gzip格式的js文件時(shí),優(yōu)先使用靜態(tài)文件
 gzip_min_length  10k; //開啟gzip壓縮的最小大小
 gzip_buffers     4 16k;
 gzip_http_version 1.1;
 gzip_comp_level 6;
 gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
 gzip_vary on;
 gzip_proxied   expired no-cache no-store private auth;
 gzip_disable   "MSIE [1-6]\.";

注意:

當(dāng)nginx開啟gzip壓縮的時(shí)候,無論前端打包出來的文件是否壓縮,網(wǎng)站加載到的js文件都是經(jīng)過nginx實(shí)時(shí)壓縮過的 。

當(dāng)gzip_static off的時(shí)候,前端上傳的js壓縮文件(gzip格式那些)并沒有什么用。

當(dāng)gzip_static on時(shí),優(yōu)先加載前端打包的gzip壓縮文件,如果沒有找到該文件,那么nginx將實(shí)時(shí)壓縮之后傳給瀏覽器。

到此這篇關(guān)于JavaScript前端實(shí)現(xiàn)頁(yè)面白屏檢測(cè)與解決的文章就介紹到這了,更多相關(guān)JavaScript頁(yè)面白屏內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論