<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你不知道的 Web 前端監(jiān)控,全面掌握應(yīng)用運(yùn)行狀況!(收藏)

          共 9490字,需瀏覽 19分鐘

           ·

          2020-10-23 18:01

          也許你有聽過一個(gè)問題,你這款 web 應(yīng)用性能怎么樣呀?你會(huì)回答什么呢?是否會(huì)優(yōu)于海量 web 應(yīng)用市場呢?本文就來整理下如何進(jìn)行 web 性能監(jiān)控?包括我們需要監(jiān)控的指標(biāo)、監(jiān)控的分類、performance 分析以及如何監(jiān)控。但是,如何進(jìn)行 web 性能監(jiān)控本身是一個(gè)很大的話題,文中只會(huì)側(cè)重一部分進(jìn)行研究,某些內(nèi)容不是很全面。

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

          web 的性能一定程度上影響了用戶留存率,Google DoubleClick 研究表明:如果一個(gè)移動(dòng)端頁面加載時(shí)長超過 3 秒,用戶就會(huì)放棄而離開。BBC 發(fā)現(xiàn)網(wǎng)頁加載時(shí)長每增加 1 秒,用戶就會(huì)流失 10%。我們希望通過監(jiān)控來知道 web 應(yīng)用性能的現(xiàn)狀和趨勢,找到 web 應(yīng)用的瓶頸?某次發(fā)布后的性能情況怎么樣?是否發(fā)布后對(duì)性能有影響?感知到業(yè)務(wù)出錯(cuò)的概率?業(yè)務(wù)的穩(wěn)定性怎么樣?

          監(jiān)控什么?

          首先我們需要知道應(yīng)該監(jiān)控些什么呢?有哪些具體的指標(biāo)?google 開發(fā)者提出了一種 RAIL 模型來衡量應(yīng)用性能,即:Response、Animation、Idle、Load,分別代表著 web 應(yīng)用生命周期的四個(gè)不同方面。并指出最好的性能指標(biāo)是:100ms 內(nèi)響應(yīng)用戶輸入;動(dòng)畫或者滾動(dòng)需在 10ms 內(nèi)產(chǎn)生下一幀;最大化空閑時(shí)間;頁面加載時(shí)長不超過 5 秒。

          0

          我們可轉(zhuǎn)化為三個(gè)方面來看:響應(yīng)速度、頁面穩(wěn)定性、外部服務(wù)調(diào)用 響應(yīng)速度:頁面初始訪問速度 + 交互響應(yīng)速度 頁面穩(wěn)定性:頁面出錯(cuò)率 外部服務(wù)調(diào)用:網(wǎng)絡(luò)請(qǐng)求訪問速度

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

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

          1

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

          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 可以獲取到,一般來說兩個(gè)時(shí)間相同,但也有情況下兩者不同。

          2)First meaningful paint and hero element timing

          首次有意義的渲染、頁面關(guān)鍵元素 我們假設(shè)當(dāng)一個(gè)網(wǎng)頁的 DOM 結(jié)構(gòu)發(fā)生劇烈的變化的時(shí)候,就是這個(gè)網(wǎng)頁主要內(nèi)容出現(xiàn)的時(shí)候,那么在這樣的一個(gè)時(shí)間點(diǎn)上,就是首次有意義的渲染。這個(gè)指標(biāo)瀏覽器還沒有規(guī)范,畢竟很難統(tǒng)一一個(gè)標(biāo)準(zhǔn)來定義網(wǎng)站的主體內(nèi)容。google lighthouse 定義的 first meaningful paint:https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view

          3)Time to interactive

          可交互時(shí)間

          4)長任務(wù)

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

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

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

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

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

          監(jiān)控的分類?

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

          合成監(jiān)控

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

          1. Lighthouse

          Lighthouse 是 google 一個(gè)開源的自動(dòng)化工具,運(yùn)行 Lighthouse 的方式有兩種:一種是作為 Chrome 擴(kuò)展程序運(yùn)行;另一種作為命令行工具運(yùn)行。Chrome 擴(kuò)展程序提供了一個(gè)對(duì)用戶更友好的界面,方便讀取報(bào)告。通過命令行工具可以將 Lighthouse 集成到持續(xù)集成系統(tǒng)。展示了白屏、首屏、可交互時(shí)間等性能指標(biāo)和 SEO、PWA 等。騰訊文檔移動(dòng)端官網(wǎng)首頁測速結(jié)果:

          2. PageSpeed

          https://developers.google.com/speed/pagespeed/insights/不僅展示了一些主要的性能指標(biāo)數(shù)據(jù),還給出了部分性能優(yōu)化建議。騰訊文檔移動(dòng)端首頁測速結(jié)果和性能優(yōu)化建議:

          3. WebPageTest

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

          4. Pingdom

          https://www.pingdom.com/注意:Pingdom 不僅提供合成監(jiān)控,也提供真實(shí)用戶監(jiān)控。

          合成監(jiān)控方式的優(yōu)缺點(diǎn):優(yōu)點(diǎn):無侵入性。簡單快捷。缺點(diǎn):不是真實(shí)的用戶訪問情況,只是模擬的。沒法考慮到登錄的情況,對(duì)于需要登錄的頁面就無法監(jiān)控到。

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

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

          1. oneapm

          https://www.oneapm.com/bi/feature.html功能包括:大盤數(shù)據(jù)、特征統(tǒng)計(jì)、慢加載追蹤、訪問頁面、腳本錯(cuò)誤、AJAX、組合分析、報(bào)表、告警等。

          2. Datadog

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

          3. FrontJs

          https://www.frontjs.com/功能包括:訪問性能、異常監(jiān)控、報(bào)表、趨勢等。

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

          performance 分析

          在講如何監(jiān)控之前,先來看看瀏覽器提供的 performance api,這也是性能監(jiān)控?cái)?shù)據(jù)的主要來源。performance 提供高精度的時(shí)間戳,精度可達(dá)納秒級(jí)別,且不會(huì)隨操作系統(tǒng)時(shí)間設(shè)置的影響。目前市場上的支持情況:主流瀏覽器都支持,大可放心使用。

          基本屬性

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

          performance.timing: 頁面加載的各階段時(shí)長

          各階段的含義:

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

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

          基本方法

          performance.getEntries() 通過這個(gè)方法可以獲取到所有的 performance 實(shí)體對(duì)象,通過 getEntriesByName 和 getEntriesByType 方法可對(duì)所有的 performance 實(shí)體對(duì)象 進(jìn)行過濾,返回特定類型的實(shí)體。mark 方法 和 measure 方法的結(jié)合可打點(diǎn)計(jì)時(shí),獲取某個(gè)函數(shù)執(zhí)行耗時(shí)等。

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

          提供的 API

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

          1. PerformanceObserver API

          用于檢測性能的事件,這個(gè) API 利用了觀察者模式。獲取資源信息

          監(jiān)測 TTI

          監(jiān)測 長任務(wù)

          2. Navigation Timing API

          https://www.w3.org/TR/navigation-timing-2/performance.getEntriesByType("navigation");

          不同階段之間是連續(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 頁面完全加載時(shí)間: loadEventStart - fetchStart http 頭部大小:transferSize - encodedBodySize

          3. Resource Timing API

          https://w3c.github.io/resource-timing/performance.getEntriesByType("resource");

          // 某類資源的加載時(shí)間,可測量圖片、js、css、XHR
          resourceListEntries.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í)間

          5. User Timing API

          https://www.w3.org/TR/user-timing-2/#introduction主要是利用 mark 和 measure 方法去打點(diǎn)計(jì)算某個(gè)階段的耗時(shí),例如某個(gè)函數(shù)的耗時(shí)等。

          6. High Resolution Time API

          https://w3c.github.io/hr-time/#dom-performance-timeorigin主要包括 now() 方法和 timeOrigin 屬性。

          7. Performance Timeline API

          https://www.w3.org/TR/performance-timeline-2/#introduction

          總結(jié)

          基于 performance 我們可以測量如下幾個(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 頁面完全加載時(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 ));

          如何監(jiān)控?

          在了解了 performance 之后,我們來看看,具體是如何監(jiān)控的?

          總體流程:性能指標(biāo)收集與數(shù)據(jù)上報(bào)—數(shù)據(jù)存儲(chǔ)—數(shù)據(jù)聚合—分析展示—告警、報(bào)表推送

          這里主要講述如何收集性能數(shù)據(jù)。性能指標(biāo)收集注意項(xiàng):1)保證數(shù)據(jù)的準(zhǔn)確性 2)盡量不影響應(yīng)用的性能

          1. 基本性能上報(bào)

          采集數(shù)據(jù):將 performance navagation timing 中的所有點(diǎn)都上報(bào),其余的上報(bào)內(nèi)容可參考 performance 分析一節(jié)中截取部分上報(bào)。例如:白屏?xí)r間,JS 和 CSS 總數(shù),以及加載總時(shí)長。其余可參考的上報(bào):是否有緩存?是否啟用 gzip 壓縮、頁面加載方式。在收集好性能數(shù)據(jù)后,即可將數(shù)據(jù)上報(bào)。那選擇什么時(shí)機(jī)上報(bào)?google 開發(fā)者推薦的上報(bào)方式:

          2. 首屏?xí)r間計(jì)算

          我們知道首屏?xí)r間是一項(xiàng)重要指標(biāo),但是又很難從 performance 中拿到,來看下首屏?xí)r間計(jì)算主要有哪些方式?https://web.dev/first-meaningful-paint/1)用戶自定義打點(diǎn)—最準(zhǔn)確的方式(只有用戶自己最清楚,什么樣的時(shí)間才算是首屏加載完成) 2)lighthouse 中使用的是 chrome 渲染過程中記錄的 trace event 3)可利用 Chrome DevTools Protocol 拿到頁面布局節(jié)點(diǎn)數(shù)目。思想是:獲取到當(dāng)頁面具有最大布局變化的時(shí)間點(diǎn) 4)aegis 的方法:利用 MutationObserver 接口,監(jiān)聽 document 對(duì)象的節(jié)點(diǎn)變化。檢查這些變化的節(jié)點(diǎn)是否顯示在首屏中,若這些節(jié)點(diǎn)在首屏中,那當(dāng)前的時(shí)間點(diǎn)即為首屏渲染時(shí)間。但是還有首屏內(nèi)圖片的加載時(shí)間需要考慮,遍歷 performance.getEntries() 拿到的所有圖片實(shí)體對(duì)象,根據(jù)圖片的初始加載時(shí)間和加載完成時(shí)間去更新首屏渲染時(shí)間。5)利用 MutationObserver 接口提供了監(jiān)視對(duì) DOM 樹所做更改的能力,是 DOM3 Events 規(guī)范的一部分。方法:在首屏內(nèi)容模塊插入一個(gè) div,利用 Mutation Observer API 監(jiān)聽該 div 的 dom 事件,判斷該 div 的高度是否大于 0 或者大于指定值,如果大于了,就表示主要內(nèi)容已經(jīng)渲染出來,可計(jì)算首屏?xí)r間。6)某個(gè)專利:在 loading 狀態(tài)下循環(huán)判斷當(dāng)前頁面高度是否大于屏幕高度,若大于,則獲取到當(dāng)前頁面的屏幕圖像,通過逐像素對(duì)比來判斷頁面渲染是否已滿屏。https://patentimages.storage.googleapis.com/bd/83/3d/f65775c31c7120/CN103324521A.pdf

          3. 異常上報(bào)

          1)js error 監(jiān)聽 window.onerror 事件 2)promise reject 的異常 監(jiān)聽 unhandledrejection 事件

          window.addEventListener("unhandledrejection", function  (event)  {
          console.warn("WARNING: Unhandled promise rejection. Shame on you! Reason: " + event.reason );
          });

          3)資源加載失敗

          window.addEventListener('error')

          4)網(wǎng)絡(luò)請(qǐng)求失敗 重寫 window.XMLHttpRequest 和 window.fetch 捕獲請(qǐng)求錯(cuò)誤 5)iframe 異常

          window.frames[0].onerror

          6)window.console.error

          4. CGI 上報(bào)

          大致原理:攔截 ajax 請(qǐng)求 數(shù)據(jù)存儲(chǔ)與聚合 一個(gè)用戶訪問,可能會(huì)上報(bào)幾十條數(shù)據(jù),每條數(shù)據(jù)都是多維度的。即:當(dāng)前訪問時(shí)間、平臺(tái)、網(wǎng)絡(luò)、ip 等。這些一條條的數(shù)據(jù)都會(huì)被存儲(chǔ)到數(shù)據(jù)庫中,然后通過數(shù)據(jù)分析與聚合,提煉出有意義的數(shù)據(jù)。例如:某日所有用戶的平均訪問時(shí)長、pv 等。

          數(shù)據(jù)統(tǒng)計(jì)分析的方法:平均值統(tǒng)計(jì)法、百分位數(shù)統(tǒng)計(jì)法、樣本分布統(tǒng)計(jì)法。

          參考文章

          1. 為什么性能如此重要:https://developers.google.cn/web/fundamentals/performance/why-performance-matters
          2. Chrome 中的 First Meaningful Paint:https://juejin.im/entry/598080226fb9a03c5d535cd5
          3. 螞蟻金服:https://www.infoq.cn/article/Dxa8aM44oz*Lukk5Ufhy
          4. FMP:https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view#heading=h.k50nnyhtptq0
          5. 如何搭建前端監(jiān)控體系:https://www.zhihu.com/question/37585246
          6. FEX-7 天打造前端性能監(jiān)控系統(tǒng):https://fex.baidu.com/blog/2014/05/build-performance-monitor-in-7-days/
          7. 首屏?xí)r間自動(dòng)化:https://cloud.tencent.com/developer/article/1061844https://segmentfault.com/a/1190000013532766
          8. 如何使用 performance api 來測量性能:https://blog.logrocket.com/how-to-practically-use-performance-api-to-measure-performance/
          9. Improving Performance with the Paint Timing API:https://www.sitepen.com/blog/improving-performance-with-the-paint-timing-api/
          10. chrome-performance 頁面性能分析使用教程:https://www.cnblogs.com/ranyonsue/p/9342839.html
          11. 阿里云前端監(jiān)控概述:https://help.aliyun.com/document_detail/58652.html?spm=a2c4g.11186623.6.627.7f782f4dsb9ZV7
          12. first load 與 first meaningful 的區(qū)別:https://webenso.com/forget-page-load-time/
          13. 其他:https://cdc.tencent.com/2018/09/13/frontend-exception-monitor-research/
          14. lightHouse 實(shí)現(xiàn)原理:https://juejin.im/post/5dca05f45188250c643b7d76
          15. Test website performance with Puppeteer:https://michaljanaszek.com/blog/test-website-performance-with-puppeteer

          最后



          如果你覺得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我三個(gè)小忙:

          1. 點(diǎn)個(gè)「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點(diǎn)在看,都是耍流氓 -_-)

          2. 歡迎加我微信「qianyu443033099」拉你進(jìn)技術(shù)群,長期交流學(xué)習(xí)...

          3. 關(guān)注公眾號(hào)「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時(shí)聊騷。


          點(diǎn)個(gè)在看支持我吧,轉(zhuǎn)發(fā)就更好了


          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色操逼| 国产A片免费看 | 色亭亭 | 人人爱人人操五月天 | 免费观看欧美成人网站 |