JavaScript錯誤對性能的影響
?雖然Web性能的實(shí)踐已經(jīng)存在了一段時(shí)間,并且多年來研究和調(diào)試JavaScript (JS)錯誤的能力有所提高,但我們從未真正關(guān)注過錯誤對性能的影響。
JavaScript錯誤是Akamai的真實(shí)用戶監(jiān)控 (RUM) 工具 (mPulse ) 收集的更復(fù)雜的指標(biāo)之一,作為一名數(shù)據(jù)科學(xué)家,我已經(jīng)研究這些數(shù)據(jù)幾年了。在這篇文章中,我將談?wù)勎业囊恍┌l(fā)現(xiàn)。
挑戰(zhàn)
那么,我們在分析JS錯誤時(shí)從哪里開始呢?任何JS錯誤跟蹤服務(wù)的用戶都會立即觀察到唯一錯誤的數(shù)量增長得非常快。這使得在數(shù)據(jù)中找到模式并最終診斷站點(diǎn)上的問題區(qū)域變得極其困難。幸運(yùn)的是,許多獨(dú)特的錯誤并不是真的那么獨(dú)特。事實(shí)上,許多錯誤彼此非常相似,只是在語法上略有不同。這些變化可能由于多種原因而發(fā)生,例如(但不限于):
(1)瀏覽器如何呈現(xiàn)錯誤的差異:
參數(shù)列表后缺少 )
SyntaxError: missing ) 在參數(shù)列表之后
(2)相同的錯誤對象引用出現(xiàn)在不同的數(shù)組索引處:
錯誤:無法解析具有未知索引“5”的 iframe
錯誤:無法解析具有未知索引“7”的 iframe
錯誤:無法解析具有未知索引“21”的 iframe
(3)不同變量名稱的相同邏輯錯誤:
ReferenceError: '$' 未定義
ReferenceError: 't' 未定義
ReferenceError: 'f' 未定義
根據(jù)客戶的不同,此類類似錯誤消息的出現(xiàn)可能會在JS錯誤數(shù)據(jù)中出現(xiàn)數(shù)十到數(shù)百次。我們通過重復(fù)數(shù)據(jù)刪除并對一組更易于管理的錯誤進(jìn)行分析,從而利用這些共性來發(fā)揮我們的優(yōu)勢。
例如,上面的第二組錯誤將成為一組錯誤,其形式為“錯誤:無法解析具有未知索引 <*> 的iframe”,其中 <*> 是索引值的占位符。
為什么對錯誤計(jì)數(shù)發(fā)出警報(bào)還不夠
了解JS錯誤何時(shí)發(fā)生以及跨越哪些頁面是了解錯誤對網(wǎng)站的影響的重要第一步。然而,簡單地監(jiān)控發(fā)生的錯誤數(shù)量并不能為監(jiān)控整個(gè)網(wǎng)絡(luò)流量提供任何額外的好處。
這里的原因是許多頁面包含JS錯誤,因此,錯誤的數(shù)量幾乎與Web流量的規(guī)模完全相關(guān)。我的mPulse 產(chǎn)品團(tuán)隊(duì)引入了一個(gè)名為“每頁錯誤數(shù)”的指標(biāo)來解決這個(gè)問題。
“每頁錯誤數(shù)”定義為JS錯誤數(shù)除以感興趣時(shí)間段的頁面瀏覽量。這使我們能夠意識到并及時(shí)了解錯誤數(shù)量相對于信標(biāo)數(shù)量激增的時(shí)間。雖然這個(gè)指標(biāo)非常有用,但不幸的是,由于JS錯誤的性質(zhì),它并不完美。在某些情況下,錯誤很普遍,但卻是良性的。也就是說,錯誤發(fā)生率高并不一定等同于糟糕的用戶體驗(yàn)或?qū)W(wǎng)絡(luò)性能的影響。在不了解其他信息的情況下,我們無法確定這種廣泛存在的錯誤是否真的具有影響力或只是以高發(fā)生率發(fā)生。出于這個(gè)原因,我們必須深入研究Web性能指標(biāo)以獲得更清晰的畫面。
表現(xiàn)
雖然較慢的頁面通常會導(dǎo)致糟糕的用戶體驗(yàn),但重要的是要密切關(guān)注似乎已經(jīng)顯著改善的指標(biāo)——那些幾乎好得令人難以置信的指標(biāo)。想象一個(gè)頁面被破壞到頁面加載過程完全中斷并且頁面加載速度非常快的情況。負(fù)責(zé)監(jiān)控網(wǎng)站健康狀況的人員可能會對與這些頁面相關(guān)的錯誤感興趣。
在我們的一項(xiàng)分析中,我們查看顯示錯誤的頁面與不存在該特定錯誤的類似頁面。然后,我們使用此分叉來檢查各種頁面加載過程的時(shí)間,以查看錯誤出現(xiàn)和不出現(xiàn)的時(shí)間是否存在差異。在這里,我們并排繪制了顯示兩種情況的頁面加載時(shí)間 (ms) 分布的箱線圖。
在圖1中,我們看到了一個(gè)示例,該示例展示了當(dāng)網(wǎng)站上不存在錯誤(左)時(shí)的頁面加載時(shí)間分布與存在此錯誤時(shí)的類似頁面(右)相比,頁面加載時(shí)間分布顯著加快。
△圖1
在圖2中,我們看到了一個(gè)相反情況的示例——當(dāng)出現(xiàn)錯誤時(shí),頁面速度顯著變慢(在中位數(shù)處慢兩倍多)。事實(shí)證明,這種情況更為常見。
△圖 2
最后,在圖3中,我們遇到了一個(gè)潛在良性錯誤的情況,無論是否存在錯誤,頁面加載過程都沒有太大差異。
△圖 3
JavaScript 錯誤的間接副作用
在分析RUM數(shù)據(jù)中的JS錯誤時(shí),我們開始考慮最終用戶在面對致命或破壞其流程的錯誤時(shí)可能會表現(xiàn)出什么樣的行為。我們在數(shù)據(jù)中看到,某些錯誤的存在會導(dǎo)致用戶沮喪的行為,這對服務(wù)于網(wǎng)站的業(yè)務(wù)有底線影響。兩個(gè)最突出的情況是重新加載和放棄(頁面退出)。
重新加載
在JS錯誤的上下文中,我們認(rèn)為會話中下一頁的重新加載(特別是重新加載的高發(fā)生率)表明錯誤本身與導(dǎo)致用戶沮喪的頁面相關(guān)聯(lián)。重新加載可能由多種原因引起,包括:
(1)由于頁面加載時(shí)間過長而導(dǎo)致的不耐煩
(2)頁面上的某些內(nèi)容未正確呈現(xiàn)
(3)該頁面顯示非200級響應(yīng)代碼
要點(diǎn)是,高重新加載率會提醒我們發(fā)生錯誤的頁面上的特定問題。
出口
知道用戶退出頁面的原因并不總是顯而易見的,尤其是與JS錯誤有關(guān)的情況。通常,用戶退出或結(jié)束會話并不值得關(guān)注。例如,考慮一個(gè)用戶剛剛完成了他們在網(wǎng)站上的預(yù)期操作(進(jìn)行了購買、找到并閱讀了特定文章等)。在這種情況下,退出站點(diǎn)是用戶會話的自然結(jié)束。但是,由于網(wǎng)頁速度慢或損壞,用戶可能會比預(yù)期更快地退出站點(diǎn)。在這里,我們對這些頁面上出現(xiàn)的JS錯誤特別感興趣。
在此分析中,我們檢查了在訪問出現(xiàn)特定錯誤的頁面后會話(訪問的頁面數(shù))持續(xù)了多長時(shí)間。例如,考慮以下5個(gè)框給出的包含5個(gè)頁面的會話。
△圖 4
假設(shè)我們在第3頁上看到一個(gè)錯誤,比如錯誤XYZ。假設(shè)會話長度為5頁,則在看到錯誤XYZ后會話中剩余的頁數(shù)為2頁。
△圖 5
但是,如果我們在會話的第5頁上看到錯誤XYZ表面,則會話中剩余頁面的數(shù)量將為0。換句話說,會話在訪問具有此錯誤XYZ的頁面后結(jié)束。
△圖 6
在此分析中,我們在看到每種類型的錯誤后匯總了會話中剩余頁面的值。然后很明顯,在用戶會話的最后一頁上完全(或幾乎完全)發(fā)現(xiàn)了客戶網(wǎng)站上的某些錯誤。這些將是我們將進(jìn)一步挖掘的錯誤,以找出可能導(dǎo)致用戶會話結(jié)束的原因。
圖7使用一系列并排的箱線圖顯示了這種分析。每個(gè)錯誤都有自己的箱線圖,沿x軸用名稱表示。y軸顯示看到錯誤后會話中的剩余頁面。剩余頁面的廣泛分布表明在錯誤浮出水面后有許多可能的用戶旅程。我們可能會得出結(jié)論,雖然該錯誤可能對某些用戶造成了破壞,但它并沒有阻止大多數(shù)用戶繼續(xù)他們的會話。這些案例位于圖7的右側(cè)。
△圖 6
更有趣的是,圖表左側(cè)更緊密的分布顯示了似乎影響用戶繼續(xù)會話能力的錯誤。具體來說,最左邊的四個(gè)錯誤就是我們所說的會話殺手。每次用戶訪問存在這些錯誤之一的頁面時(shí),在每種情況下,會話都會停止繼續(xù)。
通常,此類破壞性錯誤出現(xiàn)在一組特定的頁面尺寸值上。例如,特定版本的瀏覽器、特定頁面組、特定操作系統(tǒng)、特定地理位置,或者有時(shí)是所有這些的組合。準(zhǔn)確了解錯誤導(dǎo)致性能下降的位置為開發(fā)人員維護(hù)站點(diǎn)的健康提供了明確的行動計(jì)劃。
結(jié)論
隨著網(wǎng)絡(luò)性能工具變得越來越復(fù)雜,我們收集的數(shù)據(jù)以及我們打算用這些數(shù)據(jù)回答的問題也越來越復(fù)雜。雖然我們有關(guān)于JS錯誤的數(shù)據(jù),但分析它并不總是一個(gè)簡單的問題。我們的目標(biāo)是消除這些數(shù)據(jù)中的噪音,并查明對性能有實(shí)際影響并因此導(dǎo)致最終用戶體驗(yàn)下降的JS錯誤。
對我和我的團(tuán)隊(duì)來說,圍繞JS錯誤的分析仍然是一個(gè)活躍的研究領(lǐng)域。我歡迎對上述信息提出任何問題、意見、疑慮和一般反饋。
[1] JavaScript錯誤是通過啟用錯誤插件的開源boomerang.js 包收集的。
[2] 我們運(yùn)行基于JS錯誤之間的字符串編輯距離的聚類算法。這種分析使我們能夠根據(jù)錯誤返回的字符串將我們認(rèn)為具有相同來源的錯誤分組在一起。在上面的示例中,我們將提供一組錯誤的聚合Web 性能指標(biāo)值,而不是單獨(dú)的單個(gè)錯誤。這個(gè)集群和聚合步驟使得從數(shù)據(jù)中收集見解和確定網(wǎng)站上JS錯誤的性能影響變得更加容易。
[3] 為了維護(hù)客戶數(shù)據(jù)的機(jī)密性,我有意省略了下圖中所討論的具體錯誤。
[4] 通過performance.navigation.type返回值1給出重新加載。在計(jì)算重新加載率時(shí),我們感興趣的是在看到當(dāng)前頁面上的錯誤后,在會話中的下一頁上發(fā)生這種情況的次數(shù)。
[5] 請注意,具體的錯誤名稱替換為隨機(jī)生成的字符串。
*原文鏈接:https://calendar.perfplanet.com/2021/performance-implications-of-javascript-errors/?