关于javascript:页面监控

页面监控

一、监控页面的性能

监控页面的性能次要是根据performance对象,

performace的具体介绍:https://www.cnblogs.com/bldxh/p/6857324.html

timing对象:从输出url到用户能够应用页面的全过程工夫统计,如下图:

具体实现形式如下:

  1. 做值的时间差进行上报。
  2. 通过开启定时器,查看timing.loadEventEnd是否有值,来判断页面是否加载实现;

或者是查看timing.domContentLoadedEventEnd是否有值,来判断DOM是否加载实现,用来统计用户只是关上了页面,然而此时的图片等资源还没有加载。

  1. 通过创立 new Image()进行src赋值,进行上报统计。

监控代码如下:

// 监控网页性能 performance API
export default {
    init(cb) {
        // 上报load加载实现
        this.load(() => {
            let data = this.processData(performance.timing);
            data.type = 'loaded';
            cb(this.formatData(data));
        });
        // 上报dom 加载实现,eg:统计用户关上页面,图片还没有加载实现,就敞开页面
        this.domReady(() => {
            let data = this.processData(performance.timing);
            data.type = 'domReady';
            cb(this.formatData(data));
        })
    },
    processData(p) {
        let data = {
            prevPage: p.fetchStart - p.navigationStart, // 上一个页面到这个页面的时长
            redirect: p.redirectEnd - p.redirectStart, // 重定向的时长
            dns: p.domainLookupEnd - p.domainLookupStart, // dns解析的时长
            connect: p.connectEnd - p.connectStart, // tcp连贯的时长

            send: p.responseEnd - p.requestStart, // 响应完结到申请完结
            ttfb: p.responseStart - p.navigationStart, // 首字节接管到的时长

            whiteScreen: p.domLoading - p.navigationStart, // 白屏工夫
            dom: p.domComplete - p.domInteractive, // dom解析工夫
            load: p.loadEventEnd - p.loadEventStart,//onload的执行工夫
            domReady: p.domContentLoadedEventEnd - p.navigationStart,//domReady工夫(用户可操作工夫节点) 
            total: p.loadEventEnd - p.navigationStart,//总工夫
        }
        return data;
    },
    // load实现
    load(cb) {
        let timer;
        // 通过定时器,查看页面是否加载实现
        let check = () => {
            if (performance.timing.loadEventEnd) {
                clearInterval(timer);
                cb();
            } else {
                timer = setInterval(check, 1000);
            }
        }
        window.addEventListener('load', check);
    },
    // domReady,dom加载实现
    domReady(cb) {
        let timer;
        // 通过定时器,查看页面dom是否加载完
        let check = () => {
            if (performance.timing.domContentLoadedEventEnd) {
                clearInterval(timer);
                cb();
            } else {
                timer = setInterval(check, 1000);
            }
        }
        window.addEventListener('DOMContentLoaded', check);
    },
    // 解析data eg:{a:1,b:2} => a=1&b=2
    formatData(data) {
        let arr = [];
        for (let item in data) {
            arr.push(`${item}=${data[item]}`);
        }
        return arr.join('&');
    }

}

利用:

import performance from './performance'

performance.init((data) => {
    console.log(data);
    new Image().src = 'performance.jpg?' + data;
})

二、监控页面动态资源的加载

获取页面中引入的资源文件,能够通过以下两种形式:

  1. 通过performance的办法getEntriesByType(‘resource’),获取引入的资源列表;
  2. 定义一个性能监控对象new PerformanceObserver(),调用对象的observe办法进行监控;

具体代码如下:

// 监控页面动态资源的加载状况
export default {
    init(cb){
        if(window.PerformanceObserver){
            // 过滤本身的js: /bundle.js
            let observer = new PerformanceObserver((list, obj)=> {
                let entries = list.getEntries();
                cb(this.processData(entries[0]));
            });
            observer.observe({entryTypes: ["resource"]});
        }else{
            window.onload = ()=>{
                let data = this.processData(performance.getEntriesByType('resource'));
                cb(data);
            }
        }
    },
    // 上报数据处理
    processData(arrResource){
        let arr = [];
        for(let item of arrResource){
            arr.push({
                name:item.name,//文件名称
                initiatorType: item.initiatorType,//文件类型 script,link
                duration: item.duration,//加载工夫
            })
        }
        return arr;
    }
}

援用:

import resource from './resource'

resource.init((data) => {
    console.log(data);
})


三、 监控ajax

实现形式如下:

  1. 重写XMLHttpRequest对象的open,send 办法,解决须要上报的数据;
  2. 监听xhr对象的load,error,abort办法。

代码如下:

//  监控ajax
export default ({
    init(cb) {
        let xhr = window.XMLHttpRequest;
        let oldOpen = xhr.prototype.open;
        xhr.prototype.open = function (method, url, async, username, password) {
            this.info = {
                method, url, async, username, password
            }
            return oldOpen.apply(this, arguments)
        }
        let oldSend = xhr.prototype.send;
        xhr.prototype.send = function (value) {
            let startTime = Date.now();
            let fn = (type) => () => {
                this.info.requestTime = Date.now() - startTime;
                this.info.requestSize = value ? value.length : 0;
                this.info.responseText = this.responseText;
                this.info.responseSize = this.responseText.length;

                this.info.type = type;
                cb(this.info);
            }
            this.addEventListener('load', fn('load'), false);
            this.addEventListener('error', fn('error'), false);
            this.addEventListener('abort', fn('abort'), false);//终止申请

            return oldSend.apply(this, arguments)
        }

    }
})



利用:

import xhr from './xhr'

xhr.init((data) => {
    console.log(data);
})

四、监控页面的谬误

页面的谬误捕捉次要是用onerror办法进行监控,有以下两种形式:

  1. window.onerror只会监听到页面的js谬误;
  2. 应用addEventListener办法,利用事件捕捉,能够监听到资源的援用谬误 css,img,js;

代码如下:

// 页面的谬误捕捉
export default {
    init(cb) {
        window.onerror = function (message, source, lineno, colno, error) {
            let info = {
                message: error.message,
                name: error.name
            };
            let stack = error.stack;
            let matchUrl = stack.match(/http:\/\/[^\n]*/)[0];
            console.log(matchUrl)
            info.url = matchUrl;
            // info.filename = matchUrl.match(/http:\/\/(?:\S*)\.js/)[0];
            // console.log(info.filename)
            let [, row, colume] = matchUrl.match(/:(\d+):(\d+)/);
            info.row = row;
            info.colume = colume; // 上线的时候代码会压缩 source-map 找到对应的实在的报错
            cb(info);
        }
        // 应用error的捕捉,会监听到资源的援用谬误 css,img,js
        window.addEventListener('error', function(e){
            console.log(11,e);
        }, true);
    }

}

利用:

import errCatch from './errCatch'

errCatch.init((data) => {
    console.log(data);
})

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理