成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

聊一聊前端的監(jiān)控

Pikachu / 2109人閱讀

摘要:今天我們來聊聊前端的監(jiān)控我們?yōu)槭裁葱枰岸吮O(jiān)控為了獲取用戶行為以及跟蹤產品在用戶端的使用情況,并以監(jiān)控數(shù)據(jù)為基礎,指明產品優(yōu)化方向前端監(jiān)控分為三類性能項目數(shù)據(jù)監(jiān)控異常監(jiān)控性能監(jiān)控衡量前端的性能的指標是時間那么如何監(jiān)測時間呢,瀏覽器給我們提

今天我們來聊聊前端的監(jiān)控

我們?yōu)槭裁葱枰岸吮O(jiān)控 ?

為了獲取用戶行為以及跟蹤產品在用戶端的使用情況,并以監(jiān)控數(shù)據(jù)為基礎,指明產品優(yōu)化方向

前端監(jiān)控分為三類

性能項目

數(shù)據(jù)監(jiān)控

異常監(jiān)控

性能監(jiān)控

- 衡量前端的性能的指標是時間

那么如何監(jiān)測時間呢, 瀏覽器給我們提供了一個 API performance
來看看里面都有什么吧

它的屬性 timing 是一個PerformanceTiming 對象 , 包含了延遲相關的性能,timing里的屬性基本都是成雙成對的 都是以xxxstart --- xxxend end跟start的時間差就是我們所需要的信息

那么我們來捋一捋網(wǎng)頁打開到關閉 都有哪些時間戳記錄下來,看一張網(wǎng)頁加載流程圖

首先是navigationStart 就是地址欄開始加載 期間會執(zhí)行unload 卸載上一個網(wǎng)頁的內容 如果有重定向(同域名),就開始重定向。

fetchStart 抓取開始 頁面開始加載
domainLookupStart dns 解析開始
domainLookupEnd dns 解析結束
connectStart tcp 握手開始
connectEnd 建立連接
requestStart 請求頁面開始
responseStart 響應開始
responseEnd 響應結束
domloading dom開始加載
domInteractive dom結構樹加載完成(src外鏈資源未完成)
domcontentLoaded($(function(){})
domComplete dom 加載完畢 外鏈資源加載完畢
loadevent (window.onload=function(){} 里面的代碼加載完畢)

監(jiān)控頁面加載時間

那么我們開始寫個監(jiān)控吧 先起一個服務

serve.js

let Koa = require("koa")
let Server = require("koa-static")
let path = require("path")
let app = new Koa()

app.use(Server(path.resolve(__dirname)))

app.listen(3000,function(){
    console.log("Server is running on port 3000")
})

將serve作為靜態(tài)資源目錄 服務起在端口3000

再新建performance.js
performance.js

// 性能監(jiān)控
let time = ()=>{
    let timing = performance.timing
    let data = {
        prevPage: timing.fetchStart  - timing.navigationStart , // 上一個頁面卸載到新頁面的時間
        redirect: timing.redirectEnd  - timing.redirectStart , // 重定向時長
        dns: timing.domainLookupEnd - timing.domainLookupStart, // dns 解析時長
        tcp: timing.connectEnd - timing.connectStart ,// tcp 鏈接時長
        respone: timing.responseEnd - timing.requestStart, // 響應時長
        ttfb: timing.responseStart - timing.navigationStart, // 首字節(jié)接收到 的時長
        domReady:timing.domInteractive - timing.domLoading, // dom 準備時長
        whiteScreen:timing.domLoading - timing.navigationStart, // 白屏時間
        dom:timing.domComplete - timing.domLoading, // dom解析時間
        load:timing.loadEventEnd - timing.loadEventStart,
        total:timing.loadEventEnd - timing.navigationStart
    }
    return data 
}

//  因為檢測代碼在load里執(zhí)行   所以此時load事件未完成  檢測不到load的時間  所以我們需要設置一個定時器來監(jiān)聽load完成

let timeout = (cb)=>{
    let timer;
    let check = ()=>{
        // 加載完畢后才有performance.timing.loadEventEnd
        if(performance.timing.loadEventEnd){
            timer = null 
            cb()
        }else{
            timer = setTimeout(check,100)
        }
    }
    window.addEventListener("load",check,false)
}

let domReady = (cb)=>{
    let timer;
    let check = ()=>{
        // performance.timing.domInteractive
        if(performance.timing.domInteractive){
            timer = null 
            cb()
        }else{
            timer = setTimeout(check,100)
        }
    }
    window.addEventListener("DOMContentLoaded",check,false)
}


let _performance = {
    init(cb){
        //有可能domloaded 并未加載好 用戶就關閉網(wǎng)頁了  這種情況也希望監(jiān)聽到
        domReady(()=>{
            let data = time()
            data.type = "domReady"
            cb(data)
        })
        // dom完全加載完畢
        timeout(()=>{
            let data = time()
            data.type = "loaded"
            cb(data)
        })
    }
}

// 通過_performance.init(cb)  獲取到監(jiān)控數(shù)據(jù)

_performance.init((data)=>{console.log(data)})

html 引入performance.js


運行結果為:

然后發(fā)送圖片到服務器

// 通過_performance.init(cb)  獲取到監(jiān)控數(shù)據(jù)

let formatter = (data)=>{
    let arr = []
    for(key in data){
        arr.push(`${key}=${data[key]}`)
    }
    
    return arr.join("&")

}
_performance.init((data)=>{
    // 然后我們創(chuàng)建一張空圖片把數(shù)據(jù)發(fā)給服務器
 
    let img = new Image()
    img.src = "/p.gif?" +   formatter(data)
})


監(jiān)控頁面資源加載情況

想要監(jiān)控資源就得獲取到__proto__ 上的getEntriesByType("resource")方法
獲取到的是個數(shù)組 包含了資源請求的時間 名字type 之類的 我們所做的就是拿區(qū)我們自己需要的東西


performance.js

//代碼省略
  let resource = performance.getEntriesByType("resource")
    let data = resource.map(_=>{
        return {
            name:_.name,
            initatorType:_.initiatorType,
            duration:_.duration
        }
    })
    cb(data)
ajax請求監(jiān)控

ajax 請求監(jiān)控就簡單了
performance.js

// 為了獲取到我們所需要的參數(shù)  我們改寫一下 XMLHttpRequest.prototype.open(method,url,isAsync)


let ajax = {
    init(cb){
        let xhr = window.XMLHttpRequest
        // 保存原來的open方法
        let oldOpen = xhr.prototype.open
        console.log(oldOpen)
        xhr.prototype.open = function(method,url,isAsync = true,...args){
          
            this.info = {method,url,isAsync,message:args}
          
            return oldOpen.apply(this,arguments)
        }
        let oldSend =  xhr.prototype.send
        xhr.prototype.send = function(value){
            let start = Date.now()
            let fn = (type) => () =>{
                this.info.time = Date.now() - start
                this.info.requestSize = value ? value.length : 0
                this.info.responeSize = this.responseText.length
                this.info.type = type
                cb(this.info)
            }
            this.addEventListener("load",fn("success"),false)
            this.addEventListener("error",fn("error"),false)
            this.addEventListener("abort",fn("abort"),false)
            return oldSend.apply(this,arguments)
        }
    }
}
ajax.init((data)=>{
    console.log(data)
})

index.html

    // ajax 請求監(jiān)控  原生ajax

    var request = new XMLHttpRequest(); // 新建XMLHttpRequest對象

    request.onreadystatechange = function () { // 狀態(tài)發(fā)生變化時,函數(shù)被回調
        if (request.readyState === 4) { // 成功完成
            // 判斷響應結果:
            if (request.status === 200) {
                // 成功,通過responseText拿到響應的文本:
                
            } else {
                // 失敗,根據(jù)響應碼判斷失敗原因:
              
            }
        } else {
            // HTTP請求還在繼續(xù)...
        }
    }
    
// 發(fā)送請求:
request.open("GET", "/api/categories",true,"fet");
request.send();

結果如下

錯誤文件的捕獲

主要是通過window.onerror 事件來捕獲

let errorCatch = {
    init(cb){
       window.addEventListener("error",function(message, source, lineno, colno, error) {
           this.info = {}
           let stack = error.stack;
           let matchUrl = stack.match(/http://[^
]*/)[0]  // 獲取報錯路徑
        
           this.info.filename = matchUrl.match(/http://(?:S*).js/) ?  matchUrl.match(/http://(?:S*).js/)[0]:"html" // 獲取報錯文件;
           let [,row,col] = stack.match(/:(d+):(d+)/)  // 獲取報錯行 列
           this.info  = {
               message:error.message,
               name:error.name,
               filename:this.info.filename,  //有可能是html里的js報錯
               row,
               col,    // 真實上線的時候  需要source-map 去找到真正的行跟列
           }
           cb(this.info)
        },true) 
    }
}
errorCatch.init(data=>{console.dir(data)})

需要值得注意的是
promise 無法用此方法捕獲??! 需要另行監(jiān)聽另外的事件
另外不同域的js文件不能用此方法捕獲詳細 具體查看https://www.jianshu.com/p/315...

監(jiān)測用戶行為

主要方式是在document上監(jiān)聽事件 通過事件委托獲取事件對象 封裝info 傳給后臺

綜上所訴 大致就是這樣 這里只是簡單的介紹了下 需要深入了解的小伙伴請自行尋找相關資料, 比如火焰圖之類的

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/101777.html

相關文章

  • [一聊系列]一聊前端速度統(tǒng)計(性能統(tǒng)計)那些事兒

    摘要:性能統(tǒng)計有助于幫我們檢測網(wǎng)站的用戶體驗。這樣,我們就輕輕松松的統(tǒng)計到了首屏時間。下一章,我們將繼續(xù)聊聊百度移動版首頁那些事。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼): https://segmentfault.com/blog/frontenddriver 上一篇文章我們討論了,如何進行前端日志打點統(tǒng)計: https://segm...

    gclove 評論0 收藏0
  • [一聊系列]一聊前端速度統(tǒng)計(性能統(tǒng)計)那些事兒

    摘要:性能統(tǒng)計有助于幫我們檢測網(wǎng)站的用戶體驗。這樣,我們就輕輕松松的統(tǒng)計到了首屏時間。下一章,我們將繼續(xù)聊聊百度移動版首頁那些事。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼): https://segmentfault.com/blog/frontenddriver 上一篇文章我們討論了,如何進行前端日志打點統(tǒng)計: https://segm...

    Karuru 評論0 收藏0
  • [一聊系列]一聊WEB前端安全那些事兒

    摘要:所以今天,就和大家一起聊一聊前端的安全那些事兒。我們就聊一聊前端工程師們需要注意的那些安全知識。殊不知,這不僅僅是違反了的標準而已,也同樣會被黑客所利用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog... 隨著互聯(lián)網(wǎng)的發(fā)達,各種WEB應用也變得越來越復雜,滿足了用戶的各種需求...

    AZmake 評論0 收藏0
  • [一聊系列]一聊前端模板與渲染那些事兒

    摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現(xiàn)代應用,的大量使用,使得前端工程師們日常的開發(fā)少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...

    UCloud 評論0 收藏0

發(fā)表評論

0條評論

Pikachu

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<