Performance-report collects and reports page performance data. It is a complete and sound data report plug-in that helps you complete the following functions:

  • Current page URL (data.page)

  • Previous page URL (data.preurl)

  • Current Browser version (data.appVersion)

  • Page performance data, such as page load time, blank screen time, and DNS resolution time

  • The current page error information (data.errorList) contains (js, CSS, IMG, Ajax,fetch and other error information)

  • ResoruceList Loads performance data for all resources on the page, such as Ajax, CSS, and IMG

  • There is no need to worry about blocking pages. The compressed resource size is 6kb and the report mode is asynchronous

Github address, if you feel useful to you welcome to give a star

Github.com/wangweiange…

NPM address:

www.npmjs.com/package/per…

Complete front-end performance monitoring system

Github.com/wangweiange…


HTML page direct reference:

  • 1. Download dist/ performance-report-min.js to your local PC
  • Use the script tag to add to the header of the HTML (note: before all JS resources)

  • 3. Use the performance function to monitor and report data

<html>
<head>
	<meta charset="UTF-8">
	<title>performance test</title> <! --> <script SRC =".. /dist/performance-report.min.js"></script> <script>'http://some.com/api'}) </script> </head>Copy the code

Webpack use

npm install performance-report --save-devCopy the code
//New performance.js file
//The contents are as follows

import Performance from 'performance-report'
Performance({ 
  domain:'http://some.com/api' 
})Copy the code
//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',}).Copy the code

Framework using

Popular NVVM frameworks have their own error-catching mechanisms, so window.onError cannot be used directly to catch exceptions.

Solution: Vue and React intercept and parse errors, and insert methods provided by plug-ins into errorList to report errors


VUE usage mode

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

1, Introduce Performance 2, 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;
    leterrs = stack.match(/(.+?) /)if(errs&&errs.length) errs = errs[0]
    errs=errs.replace(/w.+js/g,The $1=>{resourceUrl=The $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 }) }Copy the code


React Usage

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

1, Introduce the 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…

After react16, Error Handling is provided. The parent component added the componentDidCatch hook function. The parent component can only listen for the exception information of the child component

//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;
    leterrs = stack.match(/(.+?) /)if(errs&&errs.length) errs = errs[0]
    errs=errs.replace(/w.+js/g,The $1=>{resourceUrl=The $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 }) }Copy the code


Parameter Description:

Full call mode

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)=>{})
})Copy the code
  • Function is passed in at the same time as domain. Function takes precedence

  • Domain: reporting API

  • Outtime: delay for reporting asynchronous data (default: 1000ms)

  • IsPage: whether to report page performance data (default: true)

  • IsResource: whether to report page resource performance data (default: true)

  • IsError: whether to report page error data (default: true)

  • FilterUrl: Ajax requests that do not need to be reported (such as livereload links in development mode)

  • Fn: custom reporting function. The reporting method can be Ajax or FETCH (optional: fetch is used by default)

External methods:

1. AddError: This method reports customized error messages to the plug-in. Error messages of vue, React, and try{}catch can be reported using this method

Case study:

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
})Copy the code


AddData: user-defined data during reporting

Case study:

Performance.addData((data)=>{
	data.name = 'wangwei'
	data.some = {
		name:'wangwie',
		age:20
	}
})Copy the code


Error handling:

The plug-in handles all error messages and reports them. There are four types of error handling

  • 1. Error message n=’resource’
  • Error n=’js’
  • 3. Ajax request error n=’ajax’
  • Fetch request error n=’fetch’

AJAX handling:

  • AJAX is divided into XMLHttpRequest and Fetch processing
  • AJAX compatibility with new versions such as jQ 1.x and 2.x requires compatibility processing
  • Intercepts all FETCH request information and collects and reports errors

All resource information processing:

  • All resource information is reported. Resource types are identified by type
  • Script: js Script resources
  • Img: image resources
  • Fetchrequest: Fetch requests resources
  • Xmlhttprequest: Ajax requests resources
  • Other: other

Operation mode:

git clonehttps://github.com/wangweianger/web-performance-report.git NPM install/development/NPM run dev/pack/NPM run build http://localhost:8080/test/ page testCopy the code

Single page procedure processing instructions:

  • For a single-page application, only the performance data of the page loaded for the first time is valid. Subsequent route hops do not have performance data of the page because the required static resources have already been loaded
  • If a new route has ajax requests or FETCH requests, all new request data is captured and reported.
  • Multi-page applications will not be affected

Parameter description:

Parameter names describe instructions
appVerfion Current Browser Information
page The current page
preUrl Back surface
errorList Error resource list information
->t Resource time
->n The resource type Resource, JS, Ajax, FETCH,other
->msg The error message
->method Resource request mode The GET and POST
->data->resourceUrl Request resource path
->data->col Js error line
->data->line Js error column
->data->status Ajax error state
->data->text Ajax error message
performance Page resource performance data (all in milliseconds)
->dnst DNS Resolution time
->tcpt TCP Setup time
->wit Bad time
->domt Dom rendering completion time
->lodt Page onload time
->radt Page preparation time
->rdit Page redirection time
->uodt Unload time
->reqt Request Request Time
->andt Page DOM parsing takes time
resoruceList Page resource performance data
->decodedBodySize Resource returns data size
->duration Resources take
->method Request way GET,POST
->name Request resource path
->nextHopProtocol HTTP Version
->type Requested Resource Type Script, IMG, fetchRequest, XMLHttprequest, other

A complete report would look something like this:

{
  "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": "Incorrect ajax request path"."data": {
        "resourceUrl": "http://mock-api.seosiwei.com/guest/home/api/shop/getHomeInitInf"."text": "Incorrect ajax request path"."status": 0}."method": "GET"
    }, 
    {
      "t": 1524050060714, 
      "n": "fetch"."msg": "Fetch request error"."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}}}Copy the code


The original address: blog.seosiwei.com/detail/30