web性能監(jiān)控及采集方式

也許你有聽(tīng)過(guò)一個(gè)問(wèn)題,你這款 web 應(yīng)用性能怎么樣呀?你會(huì)回答什么呢?是否會(huì)優(yōu)于海量 web 應(yīng)用市場(chǎng)呢?本文就來(lái)整理下如何進(jìn)行 web 性能監(jiān)控?包括我們需要監(jiān)控的指標(biāo)、監(jiān)控的分類(lèi)、performance 分析以及如何監(jiān)控。

但是,如何進(jìn)行 web 性能監(jiān)控本身是一個(gè)很大的話(huà)題,文中只會(huì)側(cè)重一部分進(jìn)行研究,某些內(nèi)容不是很全面。

前言:為什么需要監(jiān)控?

web 的性能一定程度上影響了用戶(hù)留存率,Google DoubleClick 研究表明:如果一個(gè)移動(dòng)端頁(yè)面加載時(shí)長(zhǎng)超過(guò) 3 秒,用戶(hù)就會(huì)放棄而離開(kāi)。BBC 發(fā)現(xiàn)網(wǎng)頁(yè)加載時(shí)長(zhǎng)每增加 1 秒,用戶(hù)就會(huì)流失 10%。

我們希望通過(guò)監(jiān)控來(lái)知道 web 應(yīng)用性能的現(xiàn)狀和趨勢(shì),找到 web 應(yīng)用的瓶頸?某次發(fā)布后的性能情況怎么樣?是否發(fā)布后對(duì)性能有影響?感知到業(yè)務(wù)出錯(cuò)的概率?業(yè)務(wù)的穩(wěn)定性怎么樣?

監(jiān)控什么?

首先我們需要知道應(yīng)該監(jiān)控些什么呢?有哪些具體的指標(biāo)?

google 開(kāi)發(fā)者提出了一種 RAIL 模型來(lái)衡量應(yīng)用性能,即:ResponseAnimationIdleLoad,分別代表著 web 應(yīng)用生命周期的四個(gè)不同方面。并指出最好的性能指標(biāo)是:100ms 內(nèi)響應(yīng)用戶(hù)輸入;動(dòng)畫(huà)或者滾動(dòng)需在 10ms 內(nèi)產(chǎn)生下一幀;最大化空閑時(shí)間;頁(yè)面加載時(shí)長(zhǎng)不超過(guò) 5 秒。

image

我們可轉(zhuǎn)化為三個(gè)方面來(lái)看:響應(yīng)速度、頁(yè)面穩(wěn)定性、外部服務(wù)調(diào)用

  • 響應(yīng)速度:頁(yè)面初始訪問(wèn)速度 + 交互響應(yīng)速度
  • 頁(yè)面穩(wěn)定性:頁(yè)面出錯(cuò)率
  • 外部服務(wù)調(diào)用:網(wǎng)絡(luò)請(qǐng)求訪問(wèn)速度

1.頁(yè)面訪問(wèn)速度:白屏、首屏?xí)r間、可交互時(shí)間

我們來(lái)看看 google 開(kāi)發(fā)者針對(duì)用戶(hù)體驗(yàn),提出的幾個(gè)性能指標(biāo)

image

這幾個(gè)指標(biāo)其實(shí)都是根據(jù)用戶(hù)體驗(yàn),提煉出對(duì)應(yīng)的性能指標(biāo)

image

1)first paint (FP) and first contentful paint (FCP)

首次渲染、首次有內(nèi)容的渲染

這兩個(gè)指標(biāo)瀏覽器已經(jīng)標(biāo)準(zhǔn)化了,從 performance 的 The Paint Timing API 可以獲取到,一般來(lái)說(shuō)兩個(gè)時(shí)間相同,但也有情況下兩者不同。

image

2)First meaningful paint and hero element timing

首次有意義的渲染、頁(yè)面關(guān)鍵元素

我們假設(shè)當(dāng)一個(gè)網(wǎng)頁(yè)的 DOM 結(jié)構(gòu)發(fā)生劇烈的變化的時(shí)候,就是這個(gè)網(wǎng)頁(yè)主要內(nèi)容出現(xiàn)的時(shí)候,那么在這樣的一個(gè)時(shí)間點(diǎn)上,就是首次有意義的渲染。這個(gè)指標(biāo)瀏覽器還沒(méi)有規(guī)范,畢竟很難統(tǒng)一一個(gè)標(biāo)準(zhǔn)來(lái)定義網(wǎng)站的主體內(nèi)容。

google lighthouse 定義的 first meaningful painthttps://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view

3)Time to interactive

可交互時(shí)間

4)長(zhǎng)任務(wù)

瀏覽器是單線(xiàn)程的,如果長(zhǎng)任務(wù)過(guò)多,那必然會(huì)影響著用戶(hù)響應(yīng)時(shí)長(zhǎng)。好的應(yīng)用需要最大化空閑時(shí)間,以保證能最快響應(yīng)用戶(hù)的輸入。

image

2.頁(yè)面穩(wěn)定性:頁(yè)面出錯(cuò)情況

  • 資源加載錯(cuò)誤
  • JS 執(zhí)行報(bào)錯(cuò)

3.外部服務(wù)調(diào)用

  • CGI 耗時(shí)
  • CGI 成功率
  • CDN 資源耗時(shí)

監(jiān)控的分類(lèi)?

web 性能監(jiān)控可分為兩類(lèi),一類(lèi)是合成監(jiān)控(Synthetic Monitoring,SYN),另一類(lèi)是真實(shí)用戶(hù)監(jiān)控(Real User Monitoring,RUM)

合成監(jiān)控

合成監(jiān)控是采用 web 瀏覽器模擬器來(lái)加載網(wǎng)頁(yè),通過(guò)模擬終端用戶(hù)可能的操作來(lái)采集對(duì)應(yīng)的性能指標(biāo),最后輸出一個(gè)網(wǎng)站性能報(bào)告。例如:LighthousePageSpeedWebPageTestPingdomPhantomJS 等。

1. Lighthouse

Lighthouse 是 google 一個(gè)開(kāi)源的自動(dòng)化工具,運(yùn)行 Lighthouse 的方式有兩種:一種是作為 Chrome 擴(kuò)展程序運(yùn)行;另一種作為命令行工具運(yùn)行。Chrome 擴(kuò)展程序提供了一個(gè)對(duì)用戶(hù)更友好的界面,方便讀取報(bào)告。通過(guò)命令行工具可以將 Lighthouse 集成到持續(xù)集成系統(tǒng)。

展示了白屏、首屏、可交互時(shí)間等性能指標(biāo)和 SEO、PWA 等。

騰訊文檔移動(dòng)端官網(wǎng)首頁(yè)測(cè)速結(jié)果:

image

2. PageSpeed

https://developers.google.com/speed/pagespeed/insights/

不僅展示了一些主要的性能指標(biāo)數(shù)據(jù),還給出了部分性能優(yōu)化建議。

騰訊文檔移動(dòng)端首頁(yè)測(cè)速結(jié)果和性能優(yōu)化建議:

image

3. WebPageTest

WebPageTest

給出性能測(cè)速結(jié)果和資源加載的瀑布圖。

image

4. Pingdom

https://www.pingdom.com/

注意:Pingdom 不僅提供合成監(jiān)控,也提供真實(shí)用戶(hù)監(jiān)控。

image

合成監(jiān)控方式的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

  • 無(wú)侵入性。
  • 簡(jiǎn)單快捷。缺點(diǎn):
  • 不是真實(shí)的用戶(hù)訪問(wèn)情況,只是模擬的。
  • 沒(méi)法考慮到登錄的情況,對(duì)于需要登錄的頁(yè)面就無(wú)法監(jiān)控到。

二、真實(shí)用戶(hù)監(jiān)控

真實(shí)用戶(hù)監(jiān)控是一種被動(dòng)監(jiān)控技術(shù),是一種應(yīng)用服務(wù),被監(jiān)控的 web 應(yīng)用通過(guò) sdk 等方式接入該服務(wù),將真實(shí)的用戶(hù)訪問(wèn)、交互等性能指標(biāo)數(shù)據(jù)收集上報(bào)、通過(guò)數(shù)據(jù)清洗加工后形成性能分析報(bào)表。例如 FrontJsoneapmDatadog 等。

image

1. oneapm

https://www.oneapm.com/bi/feature.html

功能包括:大盤(pán)數(shù)據(jù)、特征統(tǒng)計(jì)、慢加載追蹤、訪問(wèn)頁(yè)面、腳本錯(cuò)誤、AJAX、組合分析、報(bào)表、告警等。

image

2. Datadog

https://www.datadoghq.com/rum/

image

3. FrontJs

https://www.frontjs.com/

功能包括:訪問(wèn)性能、異常監(jiān)控、報(bào)表、趨勢(shì)等。
image

這種監(jiān)控方式的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

  • 是真實(shí)用戶(hù)訪問(wèn)情況。
  • 可以觀察歷史性能趨勢(shì)。
  • 有一些額外的功能:報(bào)表推送、監(jiān)控告警等等。缺點(diǎn):
  • 有侵入性,會(huì)一定程度上響應(yīng) web 性能。

performance 分析

在講如何監(jiān)控之前,先來(lái)看看瀏覽器提供的 performance api,這也是性能監(jiān)控?cái)?shù)據(jù)的主要來(lái)源。

performance 提供高精度的時(shí)間戳,精度可達(dá)納秒級(jí)別,且不會(huì)隨操作系統(tǒng)時(shí)間設(shè)置的影響。

目前市場(chǎng)上的支持情況:主流瀏覽器都支持,大可放心使用。

image

基本屬性

performance.navigation: 頁(yè)面是加載還是刷新、發(fā)生了多少次重定向
image

performance.timing: 頁(yè)面加載的各階段時(shí)長(zhǎng)

image

各階段的含義:

image

performance.memory:基本內(nèi)存使用情況,Chrome 添加的一個(gè)非標(biāo)準(zhǔn)擴(kuò)展

image

performance.timeorigin: 性能測(cè)量開(kāi)始時(shí)的時(shí)間的高精度時(shí)間戳

image

基本方法

performance.getEntries()

通過(guò)這個(gè)方法可以獲取到所有的 performance 實(shí)體對(duì)象,通過(guò) getEntriesByNamegetEntriesByType 方法可對(duì)所有的 performance 實(shí)體對(duì)象 進(jìn)行過(guò)濾,返回特定類(lèi)型的實(shí)體。

mark 方法 和 measure 方法的結(jié)合可打點(diǎn)計(jì)時(shí),獲取某個(gè)函數(shù)執(zhí)行耗時(shí)等。

image
  • performance.getEntriesByName()
  • performance.getEntriesByType()
  • performance.mark()
  • performance.clearMarks()
  • performance.measure()
  • performance.clearMeasures()
  • performance.now() ...

提供的 API

performance 也提供了多種 API,不同的 API 之間可能會(huì)有重疊的部分。

1. PerformanceObserver API

用于檢測(cè)性能的事件,這個(gè) API 利用了觀察者模式。

獲取資源信息
image

監(jiān)測(cè) TTI
image

監(jiān)測(cè) 長(zhǎng)任務(wù)
image

2. Navigation Timing API

https://www.w3.org/TR/navigation-timing-2/

performance.getEntriesByType("navigation");

image
image

不同階段之間是連續(xù)的嗎? —— 不連續(xù)

每個(gè)階段都一定會(huì)發(fā)生嗎?—— 不一定

  • 重定向次數(shù):performance.navigation.redirectCount
  • 重定向耗時(shí): redirectEnd - redirectStart
  • DNS 解析耗時(shí): domainLookupEnd - domainLookupStart
  • TCP 連接耗時(shí): connectEnd - connectStart
  • SSL 安全連接耗時(shí): connectEnd - secureConnectionStart
  • 網(wǎng)絡(luò)請(qǐng)求耗時(shí) (TTFB): responseStart - requestStart
  • 數(shù)據(jù)傳輸耗時(shí): responseEnd - responseStart
  • DOM 解析耗時(shí): domInteractive - responseEnd
  • 資源加載耗時(shí): loadEventStart - domContentLoadedEventEnd
  • 首包時(shí)間: responseStart - domainLookupStart
  • 白屏?xí)r間: responseEnd - fetchStart
  • 首次可交互時(shí)間: domInteractive - fetchStart
  • DOM Ready 時(shí)間: domContentLoadEventEnd - fetchStart
  • 頁(yè)面完全加載時(shí)間: loadEventStart - fetchStart
  • http 頭部大小:transferSize - encodedBodySize

3. Resource Timing APIhttps://w3c.github.io/resource-timing/

performance.getEntriesByType("resource");

image
image

image.png
// 某類(lèi)資源的加載時(shí)間,可測(cè)量圖片、js、css、
XHRresourceListEntries.forEach(resource => {   
 if (resource.initiatorType == 'img') {   
 console.info(`Time taken to load ${resource.name}: `, resource.responseEnd - resource.startTime);    
}});

這個(gè)數(shù)據(jù)和 chrome 調(diào)式工具里 network 的瀑布圖數(shù)據(jù)是一樣的。

4. paint Timing API

https://w3c.github.io/paint-timing/

首屏渲染時(shí)間、首次有內(nèi)容渲染時(shí)間
image

5. User Timing API

https://www.w3.org/TR/user-timing-2/#introduction

主要是利用 mark 和 measure 方法去打點(diǎn)計(jì)算某個(gè)階段的耗時(shí),例如某個(gè)函數(shù)的耗時(shí)等。

<head>
<script>
    // 通常在head標(biāo)簽尾部時(shí),打個(gè)標(biāo)記,這個(gè)通常會(huì)視為白屏?xí)r間
    performance.mark("first paint time");
</script>
</head>
<body>
...
<script>
    // get the first paint time
    const fp = Math.ceil(performance.getEntriesByName('first paint time')[0].startTime);
</script>
</body> 

6. High Resolution Time APIhttps://w3c.github.io/hr-time/#dom-performance-timeorigin

主要包括 now() 方法和 timeOrigin 屬性。

7. Performance Timeline APIhttps://www.w3.org/TR/performance-timeline-2/#introduction

總結(jié)

基于 performance 我們可以測(cè)量如下幾個(gè)方面:

mark、measure、navigation、resource、paint、frame。

let p = window.performance.getEntries();

重定向次數(shù):performance.navigation.redirectCount

JS 資源數(shù)量: p.filter(ele => ele.initiatorType === "script").length

CSS 資源數(shù)量:p.filter(ele => ele.initiatorType === "css").length

AJAX 請(qǐng)求數(shù)量:p.filter(ele => ele.initiatorType === "xmlhttprequest").length

IMG 資源數(shù)量:p.filter(ele => ele.initiatorType === "img").length

總資源數(shù)量: window.performance.getEntriesByType("resource").length

不重復(fù)的耗時(shí)時(shí)段區(qū)分:

  • 重定向耗時(shí): redirectEnd - redirectStart
  • DNS 解析耗時(shí): domainLookupEnd - domainLookupStart
  • TCP 連接耗時(shí): connectEnd - connectStart
  • SSL 安全連接耗時(shí): connectEnd - secureConnectionStart
  • 網(wǎng)絡(luò)請(qǐng)求耗時(shí) (TTFB): responseStart - requestStart
  • HTML 下載耗時(shí):responseEnd - responseStart
  • DOM 解析耗時(shí): domInteractive - responseEnd
  • 資源加載耗時(shí): loadEventStart - domContentLoadedEventEnd

其他組合分析:

  • 白屏?xí)r間: domLoading - fetchStart
  • 粗略首屏?xí)r間: loadEventEnd - fetchStart 或者 domInteractive - fetchStart
  • DOM Ready 時(shí)間: domContentLoadEventEnd - fetchStart
  • 頁(yè)面完全加載時(shí)間: loadEventStart - fetchStart

JS 總加載耗時(shí):

const p = window.performance.getEntries();
let cssR = p.filter(ele => ele.initiatorType === "script");
Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));

CSS 總加載耗時(shí):

const p = window.performance.getEntries();
let cssR = p.filter(ele => ele.initiatorType === "css");
Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));

npm install -g lighthouse

image.png

當(dāng)頁(yè)面鏈接至使用 target="_blank" 的另一個(gè)頁(yè)面時(shí),兩個(gè)頁(yè)面將在同一個(gè)進(jìn)程上運(yùn)行。 如果新頁(yè)面正在執(zhí)行開(kāi)銷(xiāo)極大的 JavaScript,當(dāng)前頁(yè)面性能可能會(huì)受影響。
另外,target="_blank" 也有一個(gè)安全漏洞。新的頁(yè)面可以通過(guò) window.opener 訪問(wèn)舊的窗口對(duì)象,甚至可以使用 window.opener.location = newURL 將舊頁(yè)面導(dǎo)航至不同的網(wǎng)址。

當(dāng)設(shè)置rel="noopener"時(shí)chrome會(huì)在獨(dú)立的進(jìn)程中打開(kāi)新頁(yè)面,同時(shí)會(huì)阻止window.opener,因此不存在跨窗口訪問(wèn)。

  <a target="_blank" rel="noopener" >

image.png

轉(zhuǎn)原文:騰訊前端團(tuán)隊(duì)是如何做web性能監(jiān)控的?https://mp.weixin.qq.com/s/y2jh7oT36XdmHM9fImLl_w

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380