乐趣区

关于javascript:封装一个performance监控类

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

残缺代码如下

// 在 src/utils/PerformanceMonitor.js
export 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.onload
window.onload = e => {if (oldOnload && typeof oldOnload === 'string') {oldOnload(e)
  } // 尽量不影响页面主线程
  if (window.requestIdleCallback) {window.requestIdleCallback(log)
  } else {setTimeout(log)
  }
}
退出移动版