前端性能监控,设置监控超时的工作,回传到服务器

残缺代码如下

// 在src/utils/PerformanceMonitor.jsexport default class PerformanceMonitor {    constructor() {        // 设置根底毫秒        this.SEC = 1000        // 设置超时时差        this.TIMEOUT = 10 * this.SEC        // 根底配置,上传数据        this.config = {}    }    init(option) {        // 向前兼容        if (!window.performance) return false        const { url, timeoutUrl, method = 'POST', timeout = 10000 } = option        this.config = {            url,            timeoutUrl,            method,            timeout        }    }    // 上报两项外围数据    logPackage() {        const { url, timeoutUrl, method } = this.config        const domComplete = this.getLoadTime()        const timeoutRes = this.getTimeoutRes(this.config.timeout)        // 上报页面加载工夫        this.log(url, { domeComplete }, method)        // 上报超时加载的资源列表        if (timeoutRes.length) {            this.log(timeoutUrl, { timeoutRes }, method)        }    }    // 上报数据    log(url, data = {}, type = 'POST') {        const method = type.toLowerCase()        const urlToUse = method === 'get' ? `${url}?${this.makeItStr(data)}` : url        const body = method === 'get' ? {} : { body: this.convert2FormData(data) }        // 接口,可用本人我的项目封装的axios        const init = {            method,            ...body        }        // 申请接口上报服务器        fetch(urlToUse, init).catch(e => console.log(e))    }    getTimeoutRes(limit = this.TIMEOUT) {        const isTimeout = this.setTime(limit)        // 获取资源加载工夫        const resourceTimes = performance.getEntriesByType('resource')        // 生成超时资源列表        return resourceTimes.filter(item => isTimeout(this.getDomLoadTime(item))).map(getName)    }    getDomLoadTime() {        // 获取页面加载工夫        const [{ domComplete }] = performance.getEntriesByType('navigation')        return domComplete    }    setTime(limit = this.TIMEOUT) {        time => time >= limit    }    getLoadTime({ startTime, responseEnd }) {        return responseEnd - startTime    }    getName({ name }) {        return name    }    // 生成表单数据    convert2FormData(data = {}) {        Object.entries(data).reduce((last, [key, value]) => {            if (Array.isArray(value)) {                return value.reduce((lastResult, item) => {                    lastResult.append(`${key}[]`, item)                    return lastResult                }, last)            }            last.append(key, value)            return last        }, new FormData())    }    // 拼接 GET 时的url    makeItStr(data = {}) {        Object.entries(data)            .map(([k, v]) => `${k}=${v}`)            .join('&')    }}

为了监测工具不占用主线程的 JavaScript 解析工夫。因而,最好在页面触发 onload 事件后,采纳异步加载的形式:

// 在我的项目的入口文件的底部,js按流程解析const log = async () => {  const PM = await import('/src/utils/PerformanceMonitor.js')  PM.init({ url: 'xxx', timeoutUrl: 'xxxx' })  PM.logPackage()}const oldOnload = window.onloadwindow.onload = e => { if (oldOnload && typeof oldOnload === 'string') {    oldOnload(e)  } // 尽量不影响页面主线程  if (window.requestIdleCallback) {    window.requestIdleCallback(log)  } else {    setTimeout(log)  }}