對(duì)頁(yè)面采樣判斷檢測(cè)白屏
共 2036字,需瀏覽 5分鐘
·
2024-06-07 19:56
一、為什么需要檢測(cè)白屏
白屏是最嚴(yán)重的生產(chǎn)事故之一,如果大量發(fā)生,將直接導(dǎo)致業(yè)務(wù)癱瘓。頁(yè)面白屏,絕對(duì)是讓前端開(kāi)發(fā)者最為膽寒的事情,特別是隨著 SPA 項(xiàng)目的盛行,前端白屏的情況變得更為復(fù)雜且棘手起來(lái)。
復(fù)現(xiàn)難度高,面對(duì)這樣的問(wèn)題,內(nèi)心很虛,因?yàn)閷?dǎo)致白屏出現(xiàn)的原因非常多,這不是一個(gè)明確的錯(cuò)誤,如果沒(méi)有好用的監(jiān)控工具,真不知道該從何入手。
二、分析有哪些情況下會(huì)產(chǎn)生白屏
想要檢測(cè)白屏就需要先分析會(huì)產(chǎn)生白屏的場(chǎng)景,然后對(duì)癥下藥。
1.第一種:頁(yè)面加載期間,js代碼報(bào)錯(cuò),直接導(dǎo)致白屏;這種白屏常見(jiàn)于開(kāi)發(fā)階段,也最容易被發(fā)現(xiàn)的,一般情況下不會(huì)被帶到生產(chǎn)環(huán)境。2.第二種:靜態(tài)資源加載失敗,關(guān)鍵js文件無(wú)法被引入,導(dǎo)致白屏;為了讓頁(yè)面加載更快,大部分公司都會(huì)選擇將靜態(tài)資源文件上傳到自己的CDN服務(wù)器或者第三方CDN服務(wù)器,如果CDN服務(wù)器出現(xiàn)波動(dòng),就會(huì)導(dǎo)致白屏產(chǎn)生。3.第三種:接口無(wú)法返回正常結(jié)果,或者返回空結(jié)果,導(dǎo)致頁(yè)面無(wú)法渲染數(shù)據(jù),出現(xiàn)白屏、缺省屏或骨架屏等;缺省狀態(tài)和骨架屏從某種意義上看也是屬于業(yè)務(wù)白屏的一種。4.第四種:頁(yè)面本來(lái)是好好的,但是點(diǎn)擊按鈕后,出現(xiàn)報(bào)錯(cuò),導(dǎo)致頁(yè)面白屏,這種情況是不易發(fā)現(xiàn)的,白屏效果跟第一種是相同的。
方法1:檢查DOM根節(jié)點(diǎn)是否有內(nèi)容;
原理很簡(jiǎn)單,在當(dāng)前主流的三大框架中,DOM 一般都會(huì)掛載在一個(gè)根節(jié)點(diǎn)之下(比如
),發(fā)生白屏后通常是根節(jié)點(diǎn)下所有 DOM 被卸載,該方法通過(guò)檢測(cè)根節(jié)點(diǎn)下是否掛載 DOM,若無(wú)則證明白屏
這是一種簡(jiǎn)單明了且有效的方案,但缺點(diǎn)也很明顯:其一切建立在 白屏 === 根節(jié)點(diǎn)下 DOM 被卸載 成立的前提下,缺點(diǎn)是通用性較差,對(duì)于有骨架屏的情況束手無(wú)策。
方法2:Mutation Observer 監(jiān)聽(tīng) DOM 變化;
通過(guò)此MutationObserver.MutationObserver API 監(jiān)聽(tīng)頁(yè)面 DOM 變化,每當(dāng)被指定的節(jié)點(diǎn)或子樹(shù)以及配置項(xiàng)有 DOM 變動(dòng)時(shí)都可以監(jiān)聽(tīng)到
但這個(gè)方法有兩個(gè)問(wèn)題:
1)白屏不一定是 DOM 被卸載,也有可能是壓根沒(méi)渲染,比如js代碼報(bào)錯(cuò),剛進(jìn)來(lái)就是白屏的,
2)遇到有骨架屏的項(xiàng)目,若頁(yè)面從始至終就沒(méi)變化,一直顯示骨架屏,這種情況 Mutation Observer 也無(wú)法做到準(zhǔn)確判斷
方法3:頁(yè)面截圖檢測(cè)
首先對(duì)頁(yè)面進(jìn)行截圖,將截圖與一張純白的圖片做對(duì)比,判斷兩者是否足夠相似,或者根據(jù)圖片截圖的大小來(lái)判斷。
但這個(gè)方案有兩個(gè)缺陷:
1、方案較為復(fù)雜,性能不高;一方面需要借助 canvas 實(shí)現(xiàn)前端截屏,同時(shí)需要借助復(fù)雜的算法對(duì)圖片進(jìn)行對(duì)比
2、通用性較差,對(duì)于有骨架屏或者有占位符的項(xiàng)目,對(duì)比的效果就會(huì)出現(xiàn)明顯的差異
方法4:對(duì)頁(yè)面采樣判斷
采樣對(duì)比+白屏修正機(jī)制是目前比較主流的方式??梢允褂?nbsp;document.elementsFromPoint() 方法來(lái)檢測(cè)頁(yè)面是否出現(xiàn)白屏。這個(gè)方法可以返回位于指定坐標(biāo)點(diǎn)下的所有元素。通過(guò)檢查返回的元素集合,你可以判斷頁(yè)面在特定坐標(biāo)點(diǎn)下是否有元素顯示,從而間接判斷頁(yè)面是否出現(xiàn)白屏。
以下是使用 document.elementsFromPoint() 方法來(lái)檢測(cè)頁(yè)面白屏的基本示例:
function isPageBlank() {const x = 10; // 指定檢測(cè)點(diǎn)的橫坐標(biāo)const y = 10; // 指定檢測(cè)點(diǎn)的縱坐標(biāo)const elements = document.elementsFromPoint(x, y);if (elements.length === 0) {console.log('頁(yè)面在指定坐標(biāo)點(diǎn)下出現(xiàn)白屏');return true;} else {console.log('頁(yè)面在指定坐標(biāo)點(diǎn)下有元素顯示');return false;}}// 調(diào)用函數(shù)檢測(cè)頁(yè)面是否出現(xiàn)白屏isPageBlank();
在上面的示例中,我們定義了一個(gè)函數(shù) isPageBlank(),該函數(shù)通過(guò)調(diào)用 document.elementsFromPoint() 方法來(lái)檢測(cè)頁(yè)面在指定坐標(biāo)點(diǎn)下是否出現(xiàn)白屏。如果返回的元素集合為空,即沒(méi)有元素顯示在指定坐標(biāo)點(diǎn)下,就可以判斷頁(yè)面出現(xiàn)了白屏。
