<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>

          【W(wǎng)eb技術(shù)】861- 4000字帶你了解 Web 前端監(jiān)控

          共 8183字,需瀏覽 17分鐘

           ·

          2021-02-06 08:55

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

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


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

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

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


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

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

          我們來看看 google 開發(fā)者針對用戶體驗,提出的幾個性能指標(biāo)
          這幾個指標(biāo)其實都是根據(jù)用戶體驗,提煉出對應(yīng)的性能指標(biāo)

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

          首次渲染、首次有內(nèi)容的渲染
          這兩個指標(biāo)瀏覽器已經(jīng)標(biāo)準(zhǔn)化了,從 performance 的?
          The Paint Timing API?可以獲取到,一般來說兩個時間相同,但也有情況下兩者不同。


          2)First meaningful paint and hero element timing
          首次有意義的渲染、頁面關(guān)鍵元素
          我們假設(shè)當(dāng)一個網(wǎng)頁的 DOM 結(jié)構(gòu)發(fā)生劇烈的變化的時候,就是這個網(wǎng)頁主要內(nèi)容出現(xiàn)的時候,那么在這樣的一個時間點上,就是首次有意義的渲染。這個指標(biāo)瀏覽器還沒有規(guī)范,畢竟很難統(tǒng)一一個標(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
          可交互時間
          4)長任務(wù)
          瀏覽器是單線程的,如果長任務(wù)過多,那必然會影響著用戶響應(yīng)時長。好的應(yīng)用需要最大化空閑時間,以保證能最快響應(yīng)用戶的輸入。




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

          • 資源加載錯誤
          • JS 執(zhí)行報錯

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

          • CGI 耗時
          • CGI 成功率
          • CDN 資源耗時



          • 監(jiān)控的分類?


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

          合成監(jiān)控

          合成監(jiān)控是采用 web 瀏覽器模擬器來加載網(wǎng)頁,通過模擬終端用戶可能的操作來采集對應(yīng)的性能指標(biāo),最后輸出一個網(wǎng)站性能報告。例如:LighthousePageSpeedWebPageTestPingdomPhantomJS?等。
          1. Lighthouse
          Lighthouse?是 google 一個開源的自動化工具,運行?Lighthouse?的方式有兩種:一種是作為 Chrome 擴展程序運行;另一種作為命令行工具運行。Chrome 擴展程序提供了一個對用戶更友好的界面,方便讀取報告。通過命令行工具可以將 Lighthouse 集成到持續(xù)集成系統(tǒng)。
          展示了白屏、首屏、可交互時間等性能指標(biāo)和 SEO、PWA 等。
          騰訊文檔移動端官網(wǎng)首頁測速結(jié)果:




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




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




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


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

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


          真實用戶監(jiān)控

          真實用戶監(jiān)控是一種被動監(jiān)控技術(shù),是一種應(yīng)用服務(wù),被監(jiān)控的 web 應(yīng)用通過 sdk 等方式接入該服務(wù),將真實的用戶訪問、交互等性能指標(biāo)數(shù)據(jù)收集上報、通過數(shù)據(jù)清洗加工后形成性能分析報表。例如?FrontJsoneapmDatadog?等。
          1. oneapm
          https://www.oneapm.com/bi/feature.html
          功能包括:大盤數(shù)據(jù)、特征統(tǒng)計、慢加載追蹤、訪問頁面、腳本錯誤、AJAX、組合分析、報表、告警等。
          2. Datadog
          https://www.datadoghq.com/rum/

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

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



          performance 分析


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


          基本屬性

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

          performance.timing: 頁面加載的各階段時
          各階段的含義:
          performance.memory:基本內(nèi)存使用情況,Chrome 添加的一個非標(biāo)準(zhǔn)擴展
          performance.timeorigin: 性能測量開始時的時間的高精度時間戳

          基本方法

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

          提供的 API

          performance 也提供了多種 API,不同的 API 之間可能會有重疊的部分。
          1. PerformanceObserver API
          用于檢測性能的事件,這個 API 利用了觀察者模式。
          獲取資源信息

          監(jiān)測 TTI

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

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




          不同階段之間是連續(xù)的嗎? —— 不連續(xù)
          每個階段都一定會發(fā)生嗎?—— 不一定
          • 重定向次數(shù):performance.navigation.redirectCount
          • 重定向耗時: redirectEnd - redirectStart
          • DNS 解析耗時: domainLookupEnd - domainLookupStart
          • TCP 連接耗時: connectEnd - connectStart
          • SSL 安全連接耗時: connectEnd - secureConnectionStart
          • 網(wǎng)絡(luò)請求耗時 (TTFB): responseStart - requestStart
          • 數(shù)據(jù)傳輸耗時: responseEnd - responseStart
          • DOM 解析耗時: domInteractive - responseEnd
          • 資源加載耗時: loadEventStart - domContentLoadedEventEnd
          • 首包時間: responseStart - domainLookupStart
          • 白屏?xí)r間: responseEnd - fetchStart
          • 首次可交互時間: domInteractive - fetchStart
          • DOM Ready 時間: domContentLoadEventEnd - fetchStart
          • 頁面完全加載時間: loadEventStart - fetchStart
          • http 頭部大小:transferSize - encodedBodySize
          3. Resource Timing APIhttps://w3c.github.io/resource-timing/
          performance.getEntriesByType("resource");

          // 某類資源的加載時間,可測量圖片、js、css、XHR
          resourceListEntries.forEach(resource => {
          if (resource.initiatorType == 'img') {
          console.info(`Time taken to load ${resource.name}: `, resource.responseEnd - resource.startTime);
          }
          });
          這個數(shù)據(jù)和 chrome 調(diào)式工具里 network 的瀑布圖數(shù)據(jù)是一樣的。
          4. paint Timing API
          https://w3c.github.io/paint-timing/
          首屏渲染時間、首次有內(nèi)容渲染時間

          5. User Timing API
          https://www.w3.org/TR/user-timing-2/#introduction
          主要是利用 mark 和 measure 方法去打點計算某個階段的耗時,例如某個函數(shù)的耗時等。
          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 我們可以測量如下幾個方面:
          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 請求數(shù)量:p.filter(ele => ele.initiatorType === "xmlhttprequest").length
          IMG 資源數(shù)量:p.filter(ele => ele.initiatorType === "img").length
          總資源數(shù)量:?window.performance.getEntriesByType("resource").length
          不重復(fù)的耗時時段區(qū)分:
          • 重定向耗時: redirectEnd - redirectStart
          • DNS 解析耗時: domainLookupEnd - domainLookupStart
          • TCP 連接耗時: connectEnd - connectStart
          • SSL 安全連接耗時: connectEnd - secureConnectionStart
          • 網(wǎng)絡(luò)請求耗時 (TTFB): responseStart - requestStart
          • HTML 下載耗時:responseEnd - responseStart
          • DOM 解析耗時: domInteractive - responseEnd
          • 資源加載耗時: loadEventStart - domContentLoadedEventEnd
          其他組合分析:
          • 白屏?xí)r間: domLoading - fetchStart
          • 粗略首屏?xí)r間: loadEventEnd - fetchStart 或者 domInteractive - fetchStart
          • DOM Ready 時間: domContentLoadEventEnd - fetchStart
          • 頁面完全加載時間: loadEventStart - fetchStart
          JS 總加載耗時:
          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 總加載耗時:
          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ù)上報—數(shù)據(jù)存儲—數(shù)據(jù)聚合—分析展示—告警、報表推送
          這里主要講述如何收集性能數(shù)據(jù)。
          性能指標(biāo)收集注意項:
          • 保證數(shù)據(jù)的準(zhǔn)確性
          • 盡量不影響應(yīng)用的性能

          1.基本性能上報

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

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

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

          3.異常上報

          • 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ò)請求失敗 重寫 window.XMLHttpRequest 和 window.fetch 捕獲請求錯誤
          • 5)iframe 異常 window.frames[0].onerror
          • 6)window.console.error

          4.CGI 上報

          大致原理:攔截 ajax 請求
          數(shù)據(jù)存儲與聚合
          一個用戶訪問,可能會上報幾十條數(shù)據(jù),每條數(shù)據(jù)都是多維度的。即:當(dāng)前訪問時間、平臺、網(wǎng)絡(luò)、ip 等。這些一條條的數(shù)據(jù)都會被存儲到數(shù)據(jù)庫中,然后通過數(shù)據(jù)分析與聚合,提煉出有意義的數(shù)據(jù)。例如:某日所有用戶的平均訪問時長、pv 等。
          數(shù)據(jù)統(tǒng)計分析的方法:平均值統(tǒng)計法、百分位數(shù)統(tǒng)計法、樣本分布統(tǒng)計法。
          • 本文作者:liu, summerqy

          • 本文鏈接:http://www.alloyteam.com/2020/01/14184/

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 100+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點擊“閱讀原文”查看 100+ 篇原創(chuàng)文章

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  亚洲高清毛片一区二区 | 无码日韩中文字幕豆花 | 精品人妻无码一区二区三区91 | 麻豆国产传媒精品视频 | 久久久久久 豆花视频 |