日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

一文搞懂得物前端監(jiān)控

來源: 責(zé)編: 時(shí)間:2023-11-08 22:40:20 324觀看
導(dǎo)讀一背景得物的服務(wù)端監(jiān)控是比較全面和有效的,除了上報(bào)原始日志數(shù)據(jù),還通過數(shù)據(jù)分析制定線上告警機(jī)制,調(diào)用鏈路分析,而針對前端項(xiàng)目這一塊,還是不夠全面的。對前端線上問題感應(yīng)不及時(shí),靠人肉發(fā)現(xiàn),沒有告警機(jī)制等問題,所以就有個(gè)

一背景

得物的服務(wù)端監(jiān)控是比較全面和有效的,除了上報(bào)原始日志數(shù)據(jù),還通過數(shù)據(jù)分析制定線上告警機(jī)制,調(diào)用鏈路分析,而針對前端項(xiàng)目這一塊,還是不夠全面的。對前端線上問題感應(yīng)不及時(shí),靠人肉發(fā)現(xiàn),沒有告警機(jī)制等問題,所以就有個(gè)前端監(jiān)控這個(gè)項(xiàng)目。前端監(jiān)控也確實(shí)很有必要,我們需要對線上的頁面有個(gè)全面的把控,而至于怎么做監(jiān)控,做數(shù)據(jù)上報(bào),以及數(shù)據(jù)分析,如何針對監(jiān)控?cái)?shù)據(jù)分析出有用的核心鏈路的告警等也能有個(gè)全面的認(rèn)識。本文主要是介紹得物針對監(jiān)控做了哪些事情以及對前端底層監(jiān)控手段做個(gè)總結(jié)。

二監(jiān)控類型

前端監(jiān)控的范圍很廣,如監(jiān)控性能,監(jiān)控異常,監(jiān)控告警等一系列的維度來確保我們的頁面和功能是正常的,在出現(xiàn)問題時(shí)研發(fā)可以及時(shí)做出響應(yīng),及時(shí)追蹤,定位問題。2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

性能監(jiān)控

2Cr28資訊網(wǎng)——每日最新資訊28at.com

目前前端平臺在性能監(jiān)控和異常監(jiān)控是分開的,性能監(jiān)控有專門 SDK,去做上報(bào)和分析,聯(lián)合得物 App 端上一起做了性能優(yōu)化和數(shù)據(jù)分析,這塊是獨(dú)立的。主要包括性能的上報(bào),以及性能的優(yōu)化手段。下圖是前端性能監(jiān)控方面的數(shù)據(jù)展示效果。

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

總體來說性能監(jiān)控是做的比較大的,而且監(jiān)控對提高頁面的秒開是有實(shí)際優(yōu)化指導(dǎo)意義的,離線包、預(yù)請求等都是優(yōu)化手段。2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

異常告警監(jiān)控

2Cr28資訊網(wǎng)——每日最新資訊28at.com

針對異常監(jiān)控也有單獨(dú)的平臺和 SDK 去承接和上報(bào),下圖來展示收集一些異常信息,對異常信息進(jìn)行分類,再通過設(shè)置告警機(jī)制來通知開發(fā)人員及時(shí)發(fā)現(xiàn)問題:

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

這些錯(cuò)誤類的信息不一定是我們都需要關(guān)注的,有些疑難雜癥,但是有不影響頁面展示和功能的報(bào)錯(cuò),也是可以忽略的,要知道不是所有的錯(cuò)誤都能被解決的,這個(gè)時(shí)候我們可以只關(guān)注那些影響我們頁面核心功能的部分,針對這部分做一個(gè)告警配置,例如:2Cr28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

針對告警信息,再進(jìn)一步對錯(cuò)誤進(jìn)行分析,找到能解決的問題,達(dá)到對頁面穩(wěn)定性的把控。2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

日常巡檢監(jiān)控

2Cr28資訊網(wǎng)——每日最新資訊28at.com

還有一種比較特殊的場景,針對運(yùn)營活動做的營銷會場,在各個(gè)配置的坑位去做巡檢,提前發(fā)現(xiàn)會場是否正常,有沒有白屏、API 異常等提前發(fā)現(xiàn),然后聯(lián)系相應(yīng)的人去人工處理。這種監(jiān)控模式對于要投放出去的頁面做提前檢查是很有效果的,事實(shí)證明也確實(shí)如此,提前避免了很多線上問題,很厲害。

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

三監(jiān)控知識梳理

上面幾個(gè)大類型的監(jiān)控都是前端同學(xué)在監(jiān)控方面做的努力和成果,涉及到的知識點(diǎn)也很多,同樣對于業(yè)務(wù)的把控和理解也很深入,很值得學(xué)習(xí)并了解,后面的內(nèi)容就是針對監(jiān)控做個(gè)梳理總結(jié),了解下大致的實(shí)現(xiàn)方式。

2Cr28資訊網(wǎng)——每日最新資訊28at.com

前端監(jiān)控的必要性

  • 用戶在訪問頁面的時(shí)候大致會經(jīng)歷下面的階段:
  • 向服務(wù)端請求獲取靜態(tài)資源;
  • 瀏覽器加載資源;

資源加載成功之后頁面渲染繼續(xù)運(yùn)行。2Cr28資訊網(wǎng)——每日最新資訊28at.com

這些階段都有報(bào)錯(cuò)的可能,而前端要做的就是監(jiān)控后面這階段:資源加載和頁面交互。2Cr28資訊網(wǎng)——每日最新資訊28at.com

做前端監(jiān)控也有很多其他好處, 例如:2Cr28資訊網(wǎng)——每日最新資訊28at.com

  • 第一時(shí)間上報(bào)異常,解決問題;
  • 能夠比較完整的重現(xiàn)問題用戶的操作全流程路徑,方便開發(fā)者復(fù)現(xiàn)問題,定位問題;
  • 針對頁面的 PV、UV 等信息可以為產(chǎn)品和運(yùn)營做推廣決策提供數(shù)據(jù)依據(jù)。

前端監(jiān)控是很有必要的,通過監(jiān)控,我們能在線上應(yīng)用異常時(shí),第一時(shí)間收到反饋,并及時(shí)止損。對業(yè)務(wù)的發(fā)展是有正向作用的。2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

前端監(jiān)控目標(biāo)

2Cr28資訊網(wǎng)——每日最新資訊28at.com

保證穩(wěn)定性(錯(cuò)誤監(jiān)控)

錯(cuò)誤監(jiān)控包括 JavaScript 代碼錯(cuò)誤、Promsie 錯(cuò)誤、接口(XHR,F(xiàn)etch)錯(cuò)誤、資源加載錯(cuò)誤(Script,Link等)等,這些錯(cuò)誤大多會導(dǎo)致頁面功能異常甚至白屏。2Cr28資訊網(wǎng)——每日最新資訊28at.com

提升用戶體驗(yàn)(性能監(jiān)控)

性能監(jiān)控包括頁面的加載時(shí)間、接口響應(yīng)時(shí)間等,側(cè)面反應(yīng)了用戶體驗(yàn)的好壞。2Cr28資訊網(wǎng)——每日最新資訊28at.com

  • 加載時(shí)間:頁面運(yùn)行時(shí)各個(gè)階段的加載時(shí)間;
  • TTFB(Time To First Byte)(首字節(jié)時(shí)間):瀏覽器發(fā)起第一個(gè)請求到數(shù)據(jù)返回第一個(gè)字節(jié)所消耗的時(shí)間,這個(gè)時(shí)間包含了網(wǎng)絡(luò)請求時(shí)間、后端處理時(shí)間;
  • FP(First Paint)(首次繪制):首次繪制包括了任何用戶自定義的背景繪制,它是將第一個(gè)像素點(diǎn)繪制到屏幕的時(shí)刻;
  • FCP(First Content Paint)(首次內(nèi)容繪制):首次內(nèi)容繪制是瀏覽器將第一個(gè) DOM 渲染到屏幕的時(shí)間,可以是任何文本、圖像、SVG 等的時(shí)間;
  • FMP(First Meaningful paint)(首次有意義繪制):首次有意義繪制是頁面可用性的量度標(biāo)準(zhǔn);
  • LCP(Largest Contentful Paint):視窗內(nèi)最大的圖片或者文本渲染的時(shí)間,當(dāng)最大的內(nèi)容塊渲染完的時(shí)候,基本上主內(nèi)容都加載完了,與現(xiàn)有的頁面加載指標(biāo)相比,與用戶體驗(yàn)的相關(guān)性更好;
  • FID(First Input Delay)(首次輸入延遲):用戶首次和頁面交互到頁面響應(yīng)交互的時(shí)間;
  • 卡頓:指超過 50ms 的長任務(wù),具體的指標(biāo)可以根據(jù)頁面的內(nèi)容進(jìn)行調(diào)節(jié),一般 50ms 人眼就能感覺到卡頓。

針對業(yè)務(wù)進(jìn)行統(tǒng)計(jì)

  • PV:Page View 即頁面瀏覽量或點(diǎn)擊量;
  • UV:指訪問某個(gè)站點(diǎn)的不同 IP 地址的人數(shù);
  • 頁面的停留時(shí)間:用戶在每一個(gè)頁面的停留時(shí)間。

2Cr28資訊網(wǎng)——每日最新資訊28at.com

前端監(jiān)控的流程

2Cr28資訊網(wǎng)——每日最新資訊28at.com

前端埋點(diǎn)(通過 SDK 給頁面的 DOM 都加上標(biāo)記)

  • 數(shù)據(jù)上報(bào)(收集,存儲)
  • 分析和計(jì)算(將采集到的數(shù)據(jù)進(jìn)行加工匯總)
  • 可視化展示(按照緯度將數(shù)據(jù)展示)
  • 監(jiān)控報(bào)警(發(fā)現(xiàn)異常后按一定的條件觸發(fā)報(bào)警)

2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

前端埋點(diǎn)方案

代碼埋點(diǎn)

代碼埋點(diǎn),就是項(xiàng)目中引入埋點(diǎn) SDK,手動在業(yè)務(wù)代碼中標(biāo)記,觸發(fā)埋點(diǎn)事件進(jìn)行上報(bào)。比如頁面中的某一個(gè)模塊的點(diǎn)擊事件,會在點(diǎn)擊事件的監(jiān)聽中加入觸發(fā)埋點(diǎn)的代碼 this.$track('事件名', { 需要上傳的業(yè)務(wù)數(shù)據(jù) }),將數(shù)據(jù)上報(bào)到服務(wù)器端。2Cr28資訊網(wǎng)——每日最新資訊28at.com

  • 優(yōu)點(diǎn):能夠在任何時(shí)刻,更精確的發(fā)送需要的數(shù)據(jù)信息,上報(bào)數(shù)據(jù)更靈活;
  • 缺點(diǎn):工作量大,代碼侵入太強(qiáng),過于耦合業(yè)務(wù)代碼,一次埋點(diǎn)的更改就要引起發(fā)版之類的操作。

這個(gè)方案也是我們實(shí)際項(xiàng)目中現(xiàn)有的方案。2Cr28資訊網(wǎng)——每日最新資訊28at.com

可視化埋點(diǎn)

通過可視化交互的手段,代替代碼埋點(diǎn),可以新建、編輯、修改埋點(diǎn)。在組件和頁面的維度進(jìn)行埋點(diǎn)的設(shè)計(jì)。2Cr28資訊網(wǎng)——每日最新資訊28at.com

將業(yè)務(wù)代碼和埋點(diǎn)代碼分離,提供一個(gè)可視化交互的頁面,輸入為業(yè)務(wù)代碼,通過這個(gè)可視化系統(tǒng),可以在業(yè)務(wù)代碼中自定義的增加埋點(diǎn)事件,最后輸出的代碼耦合了業(yè)務(wù)代碼和埋點(diǎn)代碼。2Cr28資訊網(wǎng)——每日最新資訊28at.com

這個(gè)方案是可以解決第一種代碼埋點(diǎn)的痛點(diǎn),也是我們目前正準(zhǔn)備做的方案。2Cr28資訊網(wǎng)——每日最新資訊28at.com

無痕埋點(diǎn)

前端的任意一個(gè)事件都被綁定一個(gè)標(biāo)識,所有的事件都被記錄下來,通過定期上傳記錄文件,配合文件解析,解析出來我們想要的數(shù)據(jù),并生成可視化報(bào)告。2Cr28資訊網(wǎng)——每日最新資訊28at.com

無痕埋點(diǎn)的優(yōu)點(diǎn)是采集全量數(shù)據(jù),不會出現(xiàn)漏埋和誤埋等現(xiàn)象。缺點(diǎn)是給數(shù)據(jù)傳輸和服務(wù)器增加壓力,也無法靈活定制數(shù)據(jù)結(jié)構(gòu)。針對業(yè)務(wù)數(shù)據(jù)的準(zhǔn)確性不高。2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

2Cr28資訊網(wǎng)——每日最新資訊28at.com

監(jiān)控腳本

日志存儲

前端的埋點(diǎn)上報(bào)需要存儲起來,這個(gè)可以使用阿里云的日志服務(wù),不需要投入開發(fā)就可以采集。2Cr28資訊網(wǎng)——每日最新資訊28at.com

新建一個(gè)項(xiàng)目比如:xxx-monitor2Cr28資訊網(wǎng)——每日最新資訊28at.com

新建一個(gè)存儲日志,根據(jù)阿里云的要求發(fā)起請求,攜帶需要上報(bào)的數(shù)據(jù):2Cr28資訊網(wǎng)——每日最新資訊28at.com

http://${project}.${host}/logstores/${logStore}/track2Cr28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

代碼中調(diào)用 Track 上報(bào)日志:2Cr28資訊網(wǎng)——每日最新資訊28at.com

日志的上報(bào)可以封裝成公共的調(diào)用方式, monitor/utils/里面放所有的工具方法;2Cr28資訊網(wǎng)——每日最新資訊28at.com

tracker.js 的實(shí)現(xiàn)就是按照阿里云的上報(bào)格式發(fā)送請求,并帶上處理好的需要上報(bào)的業(yè)務(wù)數(shù)據(jù)即可,下面的都是固定的,在日志服務(wù)建好:2Cr28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn)一個(gè) Tracker 類導(dǎo)出類的實(shí)例即可,這樣在監(jiān)控的核心代碼中直接調(diào)用 tracker.send(data),核心實(shí)現(xiàn)代碼如下:2Cr28資訊網(wǎng)——每日最新資訊28at.com

// monitor/utils/get/track.js...class SendTrackLoger {  constructor() {    this.url = `http://${project}.${host}/logstores/${logStore}/track`    this.xhr = new XMLHttpRequest()  }  send(data = {}, callback) {    const logData = {...logData}    for(let key in logs) {      if (typeof logs[key] === 'number') {        logs[key] = `${logs[key]}` // 這是阿里云的要求,字段不能是數(shù)字類型      }    }    let body = JSON.stringify({      __logs__: [logs]    })    this.xhr.open('POST', this.url, true)    this.xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')    this.xhr.setRequestHeader('x-log-apiversion', '0.6.0')    this.xhr.setRequestHeader('x-log-bodyrawsize', body.length)    this.xhr.onload = function() {      if (this.status >= 200 && this.status <= 300 || this.status === 304) {        callback && callback()      }    }    this.xhr.onerror = function(error) {      console.log(error)    }    this.xhr.send(body)  }}export default new SendTrackLoger()

這里展示的是自定義要上報(bào)的數(shù)據(jù)字段:2Cr28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片2Cr28資訊網(wǎng)——每日最新資訊28at.com

監(jiān)控錯(cuò)誤

前端需要監(jiān)控的錯(cuò)誤有兩類:2Cr28資訊網(wǎng)——每日最新資訊28at.com

  • Javascript 錯(cuò)誤(JS 錯(cuò)誤,Promise 異常)
  • 監(jiān)聽 Error 錯(cuò)誤(資源加載錯(cuò)誤)

腳本實(shí)現(xiàn)

新建一個(gè) fronend-monitor  項(xiàng)目,這個(gè)項(xiàng)目就相當(dāng)于我們的工程項(xiàng)目,監(jiān)控的核心實(shí)現(xiàn)可以寫到項(xiàng)目里面,也可以抽成 SDK 的形式 Import 引入進(jìn)來,這里先寫到項(xiàng)目中。2Cr28資訊網(wǎng)——每日最新資訊28at.com

webpack.config.js 用來打包項(xiàng)目,做接口數(shù)據(jù) Mock,測試 XHR 請求監(jiān)控接口錯(cuò)誤等。2Cr28資訊網(wǎng)——每日最新資訊28at.com

const path = require('path')const HtmlWebpackPlugin = xxxmodule.exports = {  mode: 'development',  context: process.cwd(),  entry:'./src/index.js',  output: {    path: path.resolve(__dirname, 'dist'),    filename: 'monitor.js'  },  devServer: {    contentBase: path.resolve(__dirname, 'dist'),    before(router) {      router.get('/success', function(req, res) {        res.json({ id: 1 })      })      router.post('/error', function(req, res) {        res.sendStatus(500)      })    },  },  module: {},  plugins: [    new HtmlWebpackPlugin({      template: './src/index.html',      inject: "head"    })  ]}

新建一個(gè) src/index.html 在這個(gè)里面寫一些問題代碼,然后測試監(jiān)控的錯(cuò)誤捕獲。2Cr28資訊網(wǎng)——每日最新資訊28at.com

// src/index.html<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">  <title>monitor</title></head><body>  <input id="jsErrorBtn" type="button" value="js 代碼錯(cuò)誤" notallow="btnClick()" />  <input id="promiseErrorBtn" type="button" value="promise 錯(cuò)誤" notallow="promiseClick()" />  <input id="successBtn" type="button" value="成功 ajax 請求" notallow="successAjax()" />  <input id="errorBtn" type="button" value="失敗 ajax 請求" notallow="errorAjax()" />  <script>    function btnClick() {      window.goods.type = 2    }    function promiseClick() {      new Promise((resolve, reject) => {        resolve(1)      }, () => {        console.log(123)      })    }    function successAjax() {      var xhr = new XMLHttpRequest()      xhr.open('GET', '/success',  true)      xhr.responseType = 'json'      xhr.onload = function () {        console.log(xhr.response)      }      xhr.send()    }    function errorAjax() {      var xhr = new XMLHttpRequest()      xhr.open('POST', '/error',  true)      xhr.responseType = 'json'      xhr.onload = function() {        console.log(xhr.response)      }      xhr.onerror = function(err) {        console.log(err)      }      xhr.send('name=123')    }</script></body></html>

上報(bào)未捕獲的 Javascript 錯(cuò)誤

Javascript 錯(cuò)誤分為 2 種:語法錯(cuò)誤,資源家加載錯(cuò)誤,這些錯(cuò)誤都會被 window.addEventListener('error', function(event) {})捕獲,來判斷是否是資源加載錯(cuò)誤。2Cr28資訊網(wǎng)——每日最新資訊28at.com

window.addEventListener('error', function(event) {    // 如果 target 是script link 等資源    if (event.target && (event.target.src || event.target.href)) {      const element = getElement(event.target || event.path)      tracker.send({        ...        title: document.title,        url: location.href,        timestamp: event.timeStamp,        userAgent: navigator.userAgent,        type: 'resourceError',        ...      })    } else {      tracker.send({        ...        title: document.title,        url: location.href,        timestamp: event.timeStamp,        userAgent: navigator.userAgent,        type: 'jsError',        ...      })    }  }, true)

代碼中未被捕獲的 Promise 錯(cuò)誤,要監(jiān)聽 unhandledrejection 事件 window.addEventListener('unhandledrejection', function(event) {})。2Cr28資訊網(wǎng)——每日最新資訊28at.com

// 監(jiān)聽未捕獲的 promise 錯(cuò)誤  window.addEventListener('unhandledrejection', function(event) {    // PromiseRejectionEvent    let message = ''    let stack = ''    const reason =  event.reason    let filename = ''    let lineno = ''    let colno = ''    if (reason) {      message = reason.message      stack = reason.stack      const match = stack.match(//s+at/s+(.+):(/d+):(/d+).+/)      filename = match[1]      lineno = match[2]      colno = match[3]    }    tracker.send({      ...      title: document.title,      url: location.href,      timestamp: event.timeStamp,      userAgent: navigator.userAgent,      type: 'promiseError',      ...    })  }, true)

接口異常上報(bào)

接口異常上報(bào)主要是攔截請求,攔截 XMLHttpRequest 對象,改寫 XHR 的 Open 和 Send 方法,將需要上報(bào)的數(shù)據(jù)發(fā)到阿里云存儲,監(jiān)聽 Load,Error,Abort 事件,上報(bào)數(shù)據(jù):2Cr28資訊網(wǎng)——每日最新資訊28at.com

// src/monitor/lib/xhr.jsimport tracker from '../utils/tracker'export default function injectXHR() {  // 獲取 window 上的 XMLHttpRequest 對象  const XMLHttpRequest = window.XMLHttpRequest  // 保存舊的open, send函數(shù)  const prevOpen = XMLHttpRequest.prototype.open  const prevSend = XMLHttpRequest.prototype.send  // 不可使用箭頭函數(shù),不然會找不到 this 實(shí)例  XMLHttpRequest.prototype.open = function (method, url, async, username, password) {    // 重寫open,攔截請求    // 不攔截 track 本身以及 socket, 直接放行    if (!url.match(/logstores/) && !url.match(/sockjs/)) {      this.logData = { method, url, async, username, password }    }    return prevOpen.apply(this, arguments)  }  XMLHttpRequest.prototype.send = function (body) {    // 重寫 send,攔截有 logData 的請求,獲取 body 參數(shù)    if (this.logData) {      this.logData.body = body      let startTime = Date.now()      function handler(type) {        return function (event) {          // event: ProgressEvent          let duration = Date.now() - startTime          let status = this.status          let statusText = this.statusText          console.log(event)          tracker.send({            type: 'xhr',            eventType: type,            pathname: this.logData.url,            status: `${status} ${statusText}`,            duration: `${duration}`, // 接口響應(yīng)時(shí)長            response: this.response ? JSON.stringify(this.response) : '',            params: body || '',          })        }      }      this.addEventListener('load', handler('load'), false)      this.addEventListener('error', handler('error'), false)      this.addEventListener('abort', handler('abort'), false)    }    return prevSend.apply(this, arguments)  }}

監(jiān)控白屏

白屏就是頁面上什么東西也沒有,在頁面加載完成之后,如果頁面上的空白點(diǎn)很多,就說明頁面是白屏的,需要上報(bào),這個(gè)上報(bào)的時(shí)機(jī)是:document.readyState === 'complete' 表示文檔和所有的子資源已完成加載,表示load(window.addEventListener('load')狀態(tài)事件即將被觸發(fā)。2Cr28資訊網(wǎng)——每日最新資訊28at.com

document.readyState 有三個(gè)值:loading(document正在加載),interactive(可交互,表示正在加載的狀態(tài)結(jié)束,但是圖像,樣式和框架之類的子資源仍在加載),complete 就是完成,所以監(jiān)控白屏需要在文檔都加載完成的情況下觸發(fā)。2Cr28資訊網(wǎng)——每日最新資訊28at.com

// src/monitor/utils/onload.jsexport function onload(callback) {  if (document.readyState === 'complete') {    callback()  } else {    window.addEventListener('onload', callback)  }}

監(jiān)控白屏的思路主要是:可以將可視區(qū)域中心點(diǎn)作為坐標(biāo)軸的中心,在X、Y軸上各分 10 個(gè)點(diǎn),找出這個(gè) 20 個(gè)坐標(biāo)點(diǎn)上最上層的 DOM 元素,如過這些元素是包裹元素,空白點(diǎn)數(shù)就加一,包裹元素可以自定義比如 Html Body App Root Container Content 等,空白點(diǎn)數(shù)大于 0 就上報(bào)白屏日志。2Cr28資訊網(wǎng)——每日最新資訊28at.com

export default function computedBlankScreen() {  // 包裹玉元素列表  const wrapperSelectors = ['body', 'html', '#root', '#App']  // 空白節(jié)點(diǎn)的個(gè)數(shù)  let emptyPoints = 0  // 判斷20個(gè)點(diǎn)處的元素是否是包裹元素  function isWrapper(element) {    const selector = getSelector(element)    console.log(selector)    if (wrapperSelectors.indexOf(selector) >= 0) { // 表示是在包裹元素里面,空白點(diǎn)就要加一      emptyPoints++    }  }  onload(function() {    let xElements, yElements    for (let i = 0; i <=9; i++) {      xElements = document.elementFromPoint(window.innerWidth * i / 10, window.innerHeight / 2)      yElements = document.elementFromPoint(window.innerHeight * i / 10, window.innerWidth / 2)      // document.elementFromPoint 返回的是某一個(gè)坐標(biāo)點(diǎn)的由到外的html元素的集合      isWrapper(xElements[0])      isWrapper(yElements[0])    }    if (emptyPoints >= 0) {      let centerPoint = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)      tracker.send()    }  })}

監(jiān)控卡頓

用戶交互的響應(yīng)時(shí)間如果大于某一個(gè)時(shí)間,用戶就會感覺卡頓。可以定一個(gè)時(shí)間比如 100 毫秒,就代表響應(yīng)時(shí)間長,會卡頓。2Cr28資訊網(wǎng)——每日最新資訊28at.com

PerformanceObserver 構(gòu)造函數(shù)使用給定的觀察者 Callback 生成新的PerformanceObserver 對象,當(dāng)通過 Observe() 方法注冊條目類型(需要監(jiān)控的類型)的性能條目被記錄下來時(shí),會調(diào)用該觀察者回調(diào)。2Cr28資訊網(wǎng)——每日最新資訊28at.com

所以可以 new PerformanceObserver 來監(jiān)控 longTask,監(jiān)控的資源加載如果超過 100 毫秒就表示卡頓,可以瀏覽器空閑(requestIdleCallback)的時(shí)候上報(bào)數(shù)據(jù)。2Cr28資訊網(wǎng)——每日最新資訊28at.com

....export default function longTask() {  new PerformanceObserver(function(list) {    list.getEntries().forEach(function(entry) {      if (entry.duration > 100) {        // 瀏覽器空閑的時(shí)候上報(bào)        requestIdleCallback(() => {          tracker.send({            type: 'longTask',            eventType: lastEvent.type,            startTime: formatTime(entry.startTime),            duration: formatTime(entry.duration),          });        });      }    })  }).observe({ entryTypes: ['longtask']})}

性能指標(biāo)

PerformanceObserver.observe 方法用于觀察傳入的參數(shù)中指定的性能條目類型的集合。當(dāng)記錄一個(gè)指定類型的性能條目時(shí),性能監(jiān)測對象的回調(diào)函數(shù)將會被調(diào)用。performance.timing 記錄了從輸入 URL 到頁面加載完成的所有的時(shí)間,從這些字段中可以提取對對頁面性能的監(jiān)控,通過分析這些指標(biāo)來優(yōu)化頁面的體驗(yàn),比如統(tǒng)計(jì) FMP、LCP 等,具體可以查看 MDN。2Cr28資訊網(wǎng)——每日最新資訊28at.com

統(tǒng)計(jì)pv (頁面的停留時(shí)間)

navigator.connection 對象獲取網(wǎng)絡(luò)連接的信息:effectiveType(網(wǎng)絡(luò)類型),RTT(估算餓往返時(shí)間)等,還能通過監(jiān)聽 window.addEventListener('unload')事件計(jì)算用戶在頁面的停留時(shí)間。2Cr28資訊網(wǎng)——每日最新資訊28at.com

import tracker from '../util/tracker';export function pv() {    var connection = navigator.connection;    tracker.send({        type: 'pv',        networkType: connection.effectiveType,  // 網(wǎng)絡(luò)類型        rtt: connection.rtt, // 往返時(shí)間        screen: `${window.screen.width}x${window.screen.height}` // 設(shè)備分辨率    });    let startTime = Date.now();    window.addEventListener('unload', () => {        let stayTime = Date.now() - startTime; // 頁面停留時(shí)間        tracker.send({            type: 'stayTime',            stayTime        });    }, false);}

四、總結(jié)

前端監(jiān)控是一個(gè)成熟業(yè)務(wù)線的標(biāo)配,目前最多的場景是監(jiān)控 JS 錯(cuò)誤,接口請求和性能優(yōu)化,然后根據(jù)日志信息進(jìn)行分析分類的可視化展示,在發(fā)生異常的時(shí)候通知到相應(yīng)的業(yè)務(wù)開發(fā),監(jiān)控的性能指標(biāo)給頁面的體驗(yàn)優(yōu)化提供數(shù)據(jù)對比和優(yōu)化的方向。

2Cr28資訊網(wǎng)——每日最新資訊28at.com

參考文章:

  • https://juejin.cn/post/6939703198739333127
  • https://wicg.github.io/largest-contentful-paint/
  • https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceObserver/PerformanceObserver
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Long_Tasks_API
  • https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceTiming
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator

本文鏈接:http://www.www897cc.com/showinfo-26-17850-0.html一文搞懂得物前端監(jiān)控

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 想要微信小程序+Uniapp?XBoot開源項(xiàng)目助你快速開發(fā)!

下一篇: 十個(gè)Python中的數(shù)據(jù)類型技巧

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 金华市| 阿坝县| 临桂县| 河津市| 察哈| 潮安县| 长沙市| 杭锦后旗| 长白| 马边| 剑河县| 来安县| 北票市| 北川| 淮安市| 遵义县| 阿图什市| 壶关县| 和平县| 泸溪县| 赣州市| 大石桥市| 军事| 盐亭县| 石景山区| 榆中县| 察哈| 孟村| 金湖县| 泰宁县| 黑龙江省| 乐平市| 鄄城县| 舞阳县| 邮箱| 凤翔县| 东至县| 南涧| 迁安市| 永兴县| 玛曲县|