performance-report页面性能、资源、错误、ajax,fetch请求上报插件 完善小巧

performance-report只作页面性能数据的采集和上报,是比较完整和健全的数据上报插件,它能够帮你完成如下功能:

  • 当前页面URL (data.page)css

  • 上一页面URL (data.preUrl)html

  • 当前浏览器版本信息 (data.appVersion)前端

  • 页面性能数据信息 (data.performance),例如:页面加载时间,白屏时间,dns解析时间等vue

  • 当前页面错误信息 (data.errorList) 包含(js,css,img,ajax,fetch 等错误信息)react

  • 当前页面全部资源性能数据 (data.resoruceList),例如ajax,css,img等资源加载性能数据jquery

  • 不用担忧阻塞页面,压缩资源大小6kb,上报方式为异步上报webpack

github地址,若是你以为对你有用的话欢迎给个star

github.com/wangweiange…
git

npm地址:

www.npmjs.com/package/per…
github

完整的前端性能监控系统

github.com/wangweiange…
web


html页面直接引用:

  • 一、下载 dist/performance-report.min.js 到本地
  • 使用script标签引入到html的头部(备注:放到全部js资源以前)

  • 三、使用performance函数进行数据的监听上报

<html>
<head>
	<meta charset="UTF-8">
	<title>performance test</title>
	<!-- 放到全部资源以前 防止获取不到error信息 -->
	<script src="../dist/performance-report.min.js"></script>
	<script>
		//开始上报数据
		Performance({
		    domain:'http://some.com/api', //更改为你本身的上报地址域名
		})
	</script>
</head>复制代码

webpack使用

npm install performance-report --save-dev复制代码
//New performance.js file
//The contents are as follows

import Performance from 'performance-report'
Performance({ 
  domain:'http://some.com/api' 
})复制代码
//Change webpack configuration

entry: {
    //add performance entry
    'performance':path.resolve(__dirname, '../src/performance.js'),
},

//change htmlWebpackPlugin config like this
//Attention to dependence
new htmlWebpackPlugin({
    ...
    chunks: ['performance','vendors','main'],
    chunksSortMode: 'manual',
}),复制代码

框架使用

如今流行的nvvm框架都有本身的错误捕捉机制,所以不能直接使用window.onerror来捕获异常。

解决方式:vue,react负责错误拦截、解析,调用插件提供的方法插入到errorlist中进行上报


VUE使用方式

If you use the Vue framework, you can do it like this.

一、Introduce Performance
二、Copy the following code

import Performance from 'performance-report'

Vue.config.errorHandler = function (err, vm, info) {
    let { message, stack } = err;

    // Processing error
    let resourceUrl,col,line;
    let errs = stack.match(/(.+?)/)
    if(errs&&errs.length) errs = errs[0]
    errs=errs.replace(/w.+js/g,$1=>{resourceUrl=$1;return '';})
    errs=errs.split(':')
    if(errs&&errs.length>1)line=parseInt(errs[1]||0);col=parseInt(errs[2]||0)

    // Fixed parameters
    // Call the Performance.addError method
    Performance.addError({
      msg:message,
      col:col,
      line:line,
      resourceUrl:resourceUrl
    })
}复制代码


React使用方式

If you use the React framework, you can do it like this.

一、Introduce Performance

二、Error Handling in React 16.

If you don't know Error Handling.Go to the official website to understand

reactjs.org/blog/2017/0…

react16以后提供Error Handling处理报错机制,父组件新增componentDidCatch钩子函数,父组件只能监听子组件的异常信息

//Top reference
import Performance from 'performance-report'

//Parent component listens for subcomponent error information
componentDidCatch(error, info) {
    let {message,stack} = error  

    // Processing error
    let resourceUrl,col,line;
    let errs = stack.match(/(.+?)/)
    if(errs&&errs.length) errs = errs[0]
    errs=errs.replace(/w.+js/g,$1=>{resourceUrl=$1;return '';})
    errs=errs.split(':')
    if(errs&&errs.length>1)line=parseInt(errs[1]||0);col=parseInt(errs[2]||0)

    // Fixed parameters
    // Call the Performance.addError method
    Performance.addError({
      msg:message,
      col:col,
      line:line,
      resourceUrl:resourceUrl
    })
}复制代码


参数说明:

完整调用方式

Performance({
    domain:'http://some.com/api', 
    outtime:500,
    isPage:true,
    isResource:true,
    isError:true,
    filterUrl:['http://localhost:35729/livereload.js?snipver=1']
},(data)=>{
	fetch('http://some.com/api',{type:'POST',body:JSON.stringify(result)}).then((data)=>{})
})复制代码
  • 同时传入 domain和传入的function ,function优先级更高

  • domain :上报api接口

  • outtime :上报延迟时间,保证异步数据的加载 (默认:1000ms)

  • isPage :是否上报页面性能数据 (默认:true)

  • isResource :是否上报页面资源性能数据 (默认:true)

  • isError :是否上报页面错误信息数据 (默认:true)

  • filterUrl :不须要上报的ajax请求 (例如开发模式下的livereload连接)

  • fn :自定义上报函数,上报方式能够用ajax能够用fetch (非必填:默认使用fetch)

对外方法:

一:addError :此方法向插件中自定义上报错误信息,vue,react,try{}catch 的报错信息都可采用此方法上报

案例:

let message = 'js add error'
let col = 20
let line = 20
let resourceUrl = 'http://www.xxx.com/01.js'

Performance.addError({
      msg:message,
      col:col,
      line:line,
      resourceUrl:resourceUrl
})复制代码


二:addData :上报时自定义的数据

案例:

Performance.addData((data)=>{
	data.name = 'wangwei'
	data.some = {
		name:'wangwie',
		age:20
	}
})复制代码


错误处理:

插件会处理全部的error信息并完成上报,错误处理分为4种类型

  • 1.图片资源,js资源文本资源等资源错误信息 n='resource'
  • 2.js报错,代码中的js报错 n='js'
  • 3.ajax请求错误 n='ajax'
  • 4.fetch请求错误 n='fetch'

AJAX处理:

  • AJAX分为 XMLHttpRequest 和 Fetch的处理
  • AJAX兼容老板般与新版本 例如:jq的1.x版本与2.x版本以上须要作兼容处理
  • 拦截全部fetch请求信息,遇到错误时收集并上报

全部资源信息处理:

  • 上报全部资源信息,资源类型以type来区分 type类型有
  • script:js脚本资源
  • img:图片资源
  • fetchrequest:fetch请求资源
  • xmlhttprequest:ajax请求资源
  • other :其余

运行方式:

git clone https://github.com/wangweianger/web-performance-report.git
npm install
//开发
npm run dev
//打包
npm run build

http://localhost:8080/test/ 页面测试复制代码

单页面程序处理说明:

  • 对于单页面应用程序,只有第一次加载的页面性能数据有效,以后的路由跳转不会有页面的性能数据,由于须要的静态资源已经加载完成
  • 若是新的路由有ajax请求或者fetch请求,会抓取全部新的请求数据并上报。
  • 多页面应用程序不会受影响

返回参数说明:

参数名 描述 说明
appVerfion 当前浏览器信息
page 当前页面
preUrl 上一页面
errorList 错误资源列表信息
->t 资源时间
->n 资源类型 resource,js,ajax,fetch,other
->msg 错误信息
->method 资源请求方式 GET,POST
->data->resourceUrl 请求资源路径
->data->col js错误行
->data->line js错误列
->data->status ajax错误状态
->data->text ajax错误信息
performance 页面资源性能数据(单位均为毫秒)
->dnst DNS解析时间
->tcpt TCP创建时间
->wit 白屏时间
->domt dom渲染完成时间
->lodt 页面onload时间
->radt 页面准备时间
->rdit 页面重定向时间
->uodt unload时间
->reqt request请求耗时
->andt 页面解析dom耗时
resoruceList 页面资源性能数据
->decodedBodySize 资源返回数据大小
->duration 资源耗时
->method 请求方式 GET,POST
->name 请求资源路径
->nextHopProtocol http协议版本
->type 请求资源类型 script,img,fetchrequest,xmlhttprequest,other

一份完整的上报数据看起来像这样:

{
  "page": "http://localhost:8080/test/", 
  "preUrl": "", 
  "appVersion": "5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", 
  "errorList": [
    {
      "t": 1524050060518, 
      "n": "resource", 
      "msg": "img is load error", 
      "data": {
        "target": "img", 
        "type": "error", 
        "resourceUrl": "http://img1.imgtn.bd95510/"
      }, 
      "method": "GET"
    }, 
    {
      "t": 1524050060674, 
      "n": "js", 
      "msg": "ReferenceError: wangwei is not defined at http://localhost:8080/test/:73:15", 
      "data": {
        "resourceUrl": "http://localhost:8080/test/", 
        "line": 73, 
        "col": 15
      }, 
      "method": "GET"
    }, 
    {
      "t": 1524050060707, 
      "n": "ajax", 
      "msg": "ajax请求路径有误", 
      "data": {
        "resourceUrl": "http://mock-api.seosiwei.com/guest/home/api/shop/getHomeInitInf", 
        "text": "ajax请求路径有误", 
        "status": 0
      }, 
      "method": "GET"
    }, 
    {
      "t": 1524050060714, 
      "n": "fetch", 
      "msg": "fetch请求错误", 
      "data": {
        "resourceUrl": "http://mock-api.seosiwei.com/guest/order/api/order/getOrde", 
        "text": "TypeError: Failed to fetch", 
        "status": 0
      }, 
      "method": "POST"
    }
  ], 
  "performance": {
    "dnst": 0, 
    "tcpt": 1, 
    "wit": 17, 
    "domt": 165, 
    "lodt": 379, 
    "radt": 6, 
    "rdit": 0, 
    "uodt": 0, 
    "reqt": 16, 
    "andt": 210
  }, 
  "resourceList": [
    {
      "name": "http://localhost:8080/dist/performance-report.js", 
      "method": "GET", 
      "type": "script", 
      "duration": "71.60", 
      "decodedBodySize": 18592, 
      "nextHopProtocol": "http/1.1"
    }, 
    {
      "name": "https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js", 
      "method": "GET", 
      "type": "script", 
      "duration": "0.00", 
      "decodedBodySize": 0, 
      "nextHopProtocol": "h2"
    }, 
    {
      "name": "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=295864288,1887240069&fm=27&gp=0.jpg", 
      "method": "GET", 
      "type": "img", 
      "duration": "0.00", 
      "decodedBodySize": 0, 
      "nextHopProtocol": "http/1.1"
    }, 
    {
      "name": "http://localhost:35729/livereload.js?snipver=1", 
      "method": "GET", 
      "type": "script", 
      "duration": "149.20", 
      "decodedBodySize": 0, 
      "nextHopProtocol": "http/1.1"
    }, 
    {
      "name": "http://mock-api.seosiwei.com/guest/home/api/shop/getHomeInitInfo", 
      "method": "GET", 
      "type": "fetchrequest", 
      "duration": "38.30", 
      "decodedBodySize": 0, 
      "nextHopProtocol": "http/1.1"
    }, 
    {
      "name": "http://mock-api.seosiwei.com/guest/order/api/order/getOrder", 
      "method": "POST", 
      "type": "xmlhttprequest", 
      "duration": "42.30", 
      "decodedBodySize": 0, 
      "nextHopProtocol": "http/1.1"
    }
  ], 
  "addData": {
    "name": "wangwei", 
    "some": {
      "name": "wangwie", 
      "age": 20
    }
  }
}复制代码


原文地址:blog.seosiwei.com/detail/30

相关文章
相关标签/搜索