An overview of

  • Why do front-end monitoring
  • Front-end monitoring target
  • Front-end monitoring process
  • Writing collection scripts
    • Log System Monitoring
    • Monitoring errors
    • Abnormal interface
    • White during monitoring
    • Loading time
    • Performance indicators
    • caton
    • pv
  • Extension problem
    1. Performance Monitoring Indicators
    2. How does the front end monitor performance
    3. What about online error monitoring
    4. How do you monitor memory leaks
    5. How does Node perform performance monitoring

1. Why front-end monitoring

  • Identify problems and solve them faster
  • Make product decision basis
  • It provides more possibilities for business expansion
  • Enhance the technical depth and breadth of front-end engineers, and create resume highlights

2. Front-end monitoring target

2.1 Stability stability

  • Js errors: JS execution errors, promise exceptions
  • Resource error: The LOADING of JS and CSS resources is abnormal
  • Interface error: The Ajax or FETCH request interface is abnormal
  • Blank screen: The page is blank

2.2 用户体验 experience

2.3 business business

  • Pv: Page views and clicks
  • Uv: The number of people accessing different IP addresses of a site
  • The amount of time a user spends on each page

3. Front-end monitoring process

  1. The front-end buried point
  2. The data reported
  3. Processing the summary
  4. Visual presentation
  5. Monitoring alarm

3.1 Common buried point schemes

3.1.1 Code burying point

  • The form of embedded code
  • Advantages: accuracy (at any time, comprehensive data volume)
  • Cons: Code workload points

3.1.2 Visualization of buried points

  • By means of visual interaction, instead of code burying points
  • Business code and buried code separation, provide a visual interaction page, input for business code, through this system, can be customized in the business code to add buried events, etc., the final output of the code coupling business code and buried code
  • Use the system instead of manually inserting buried code

3.1.3 Traceless burial point

  • Any event in the front end is bound to an identifier, and all events are logged
  • By regularly uploading record files and cooperating with file analysis, we can parse out the data we want and generate visual reports for professional analysis
  • The advantage of traceless burial point is to collect full data, and there will be no leakage and misburial
  • The downside is that it puts pressure on the data transfer and the server, as well as the flexibility to customize the data structure

4. Write collection scripts

4.1 Adding a Log System

  • Companies generally have their own log systems to receive and report data, such as Aliyun

4.2 Monitoring Errors

4.2.1 Misclassification

  • Js error (JS execution error, promise exception)
  • Resource loading exception: Listen for error

4.2.2 Data structure analysis

1. jsError
{
    "title": "Front-end monitoring system".// Page title
    "url": "http://localhost:8080/"./ / page URL
    "timestamp": "1590815288710".// Access the timestamp
    "userAgent": "Chrome".// User browser type
    "kind": "stability"./ / categories:
    "type": "error"./ / class
    "errorType": "jsError".// Error type
    "message": "Uncaught TypeError: Cannot set property 'error' of undefined".// Type details
    "filename": "http://localhost:8080/".// Access the file name
    "position": "At".// Column information
    "stack": "btnClick (http://localhost:8080/:20:39)^HTMLInputElement.onclick (http://localhost:8080/:14:72)".// Stack information
    "selector": "HTML BODY #container .content INPUT" / / selector
}
Copy the code
2. promiseError
{..."errorType": "promiseError".// Error type
    "message": "someVar is not defined".// Type details
    "stack": "http://localhost:8080/:24:29^new Promise (<anonymous>)^btnPromiseClick (http://localhost:8080/:23:13)^HTMLInputElement.onclick (http://localhost:8080/:15:86)".// Stack information
    "selector": "HTML BODY #container .content INPUT"/ / selector
}
Copy the code
3. resourceError
."errorType": "resourceError".// Error type
    "filename": "http://localhost:8080/error.js".// Access the file name
    "tagName": "SCRIPT"./ / tag name
    "timeStamp": "76"./ / time
Copy the code

Holdings implementation

1. Resource loading error + JS execution error
// General JS runtime errors are caught using window.onerror
window.addEventListener(
  "error".function (event) {
    let lastEvent = getLastEvent();
    // there is an e.target.src(href) identified as a resource loading error
    if (event.target && (event.target.src || event.target.href)) {
      tracker.send({
        // Resource loading error
        kind: "stability".// Stability index
        type: "error".//resource
        errorType: "resourceError".filename: event.target.src || event.target.href, // Failed to load the resource
        tagName: event.target.tagName, / / tag name
        timeStamp: formatTime(event.timeStamp), / / time
        selector: getSelector(event.path || event.target), / / selector
      });
    } else {
      tracker.send({
        kind: "stability".// Stability index
        type: "error".//error
        errorType: "jsError".//jsError
        message: event.message, // An error message was reported
        filename: event.filename, // Error link reported
        position: (event.lineNo || 0) + ":" + (event.columnNo || 0), / / number
        stack: getLines(event.error.stack), // Error stack
        selector: lastEvent
          ? getSelector(lastEvent.path || lastEvent.target)
          : ""./ / CSS selector}); }},true
); // True means called in the capture phase,false means caught in the bubble phase, either true or false
Copy the code
2. Promise
// When a Promise is rejected and there is no Reject handler, the unhandledrejection event is emitted
window.addEventListener(
  "unhandledrejection".function (event) {
    let lastEvent = getLastEvent();
    let message = "";
    let line = 0;
    let column = 0;
    let file = "";
    let stack = "";
    if (typeof event.reason === "string") {
      message = event.reason;
    } else if (typeof event.reason === "object") {
      message = event.reason.message;
    }
    let reason = event.reason;
    if (typeof reason === "object") {
      if (reason.stack) {
        var matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
        if (matchResult) {
          file = matchResult[1];
          line = matchResult[2];
          column = matchResult[3];
        }
        stack = getLines(reason.stack);
      }
    }
    tracker.send({
      // Failed to catch a promise error
      kind: "stability".// Stability index
      type: "error".//jsError
      errorType: "promiseError".//unhandledrejection
      message: message, / / tag name
      filename: file,
      position: line + ":" + column, / / the ranks
      stack,
      selector: lastEvent
        ? getSelector(lastEvent.path || lastEvent.target)
        : ""}); },true
); // True means called in the capture phase,false means caught in the bubble phase, either true or false
Copy the code

4.3 Interface Exception Collection script

4.3.1 Data design

{
  "title": "Front-end monitoring system"./ / title
  "url": "http://localhost:8080/".//url
  "timestamp": "1590817024490".//timestamp
  "userAgent": "Chrome".// Browser version
  "kind": "stability"./ / categories:
  "type": "xhr"./ / class
  "eventType": "load".// Event type
  "pathname": "/success"./ / path
  "status": "200-OK"./ / status code
  "duration": "Seven".// The duration
  "response": "{\"id\":1}".// Response content
  "params": "" / / parameters
}
Copy the code
{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590817025617"."userAgent": "Chrome"."kind": "stability"."type": "xhr"."eventType": "load"."pathname": "/error"."status": "500-Internal Server Error"."duration": "Seven"."response": ""."params": "name=zhufeng"
}
Copy the code

4.3.2 implementation

Simulate requests using WebPack devServer

  • Rewrite XHR’s open and send methods
  • Listen for load, ERROR, and abort events
import tracker from ".. /util/tracker";
export function injectXHR() {
  let XMLHttpRequest = window.XMLHttpRequest;
  let oldOpen = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function (
    method,
    url,
    async,
    username,
    password
  ) {
    // The interface reported does not need to be processed
    if(! url.match(/logstores/) && !url.match(/sockjs/)) {
      this.logData = {
        method,
        url,
        async,
        username,
        password,
      };
    }
    return oldOpen.apply(this.arguments);
  };
  let oldSend = XMLHttpRequest.prototype.send;
  let start;
  XMLHttpRequest.prototype.send = function (body) {
    if (this.logData) {
      start = Date.now();
      let handler = (type) = > (event) = > {
        let duration = Date.now() - start;
        let status = this.status;
        let statusText = this.statusText;
        tracker.send({
          // Failed to catch a promise error
          kind: "stability".// Stability index
          type: "xhr".//xhr
          eventType: type, //load error abort
          pathname: this.logData.url, // The url of the interface
          status: status + "-" + statusText,
          duration: "" + duration, // The interface takes time
          response: this.response ? JSON.stringify(this.response) : "".params: body || ""}); };this.addEventListener("load", handler("load"), false);
      this.addEventListener("error", handler("error"), false);
      this.addEventListener("abort", handler("abort"), false);
    }
    oldSend.apply(this.arguments);
  };
}
Copy the code

4.4 white

  • A blank screen is nothing on the page, right

4.4.1 Data design

{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590822618759"."userAgent": "chrome"."kind": "stability"./ / categories:
  "type": "blank"./ / class
  "emptyPoints": "0"./ / the bare
  "screen": "2049x1152"./ / resolution
  "viewPoint": "2048x994"./ / viewport
  "selector": "HTML BODY #container" / / selector
}
Copy the code

4.4.2 implementation

  • The elementsFromPoint method retrieves all elements arranged from the inside out at the specified coordinates in the current viewport
  • According to the elementsFromPoint API, get the element where the horizontal and vertical center of the screen are located
import tracker from ".. /util/tracker";
import onload from ".. /util/onload";
function getSelector(element) {
  var selector;
  if (element.id) {
    selector = ` #${element.id}`;
  } else if (element.className && typeof element.className === "string") {
    selector =
      "." +
      element.className
        .split("")
        .filter(function (item) {
          return!!!!! item; }) .join(".");
  } else {
    selector = element.nodeName.toLowerCase();
  }
  return selector;
}
export function blankScreen() {
  const wrapperSelectors = ["body"."html"."#container".".content"];
  let emptyPoints = 0;
  function isWrapper(element) {
    let selector = getSelector(element);
    if (wrapperSelectors.indexOf(selector) >= 0) {
      emptyPoints++;
    }
  }
  onload(function () {
    let xElements, yElements;
    debugger;
    for (let i = 1; i <= 9; i++) {
      xElements = document.elementsFromPoint(
        (window.innerWidth * i) / 10.window.innerHeight / 2
      );
      yElements = document.elementsFromPoint(
        window.innerWidth / 2,
        (window.innerHeight * i) / 10
      );
      isWrapper(xElements[0]);
      isWrapper(yElements[0]);
    }
    if (emptyPoints >= 0) {
      let centerElements = document.elementsFromPoint(
        window.innerWidth / 2.window.innerHeight / 2
      );
      tracker.send({
        kind: "stability".type: "blank".emptyPoints: "" + emptyPoints,
        screen: window.screen.width + "x" + window.screen.height,
        viewPoint: window.innerWidth + "x" + window.innerHeight,
        selector: getSelector(centerElements[0])}); }}); }//screen.width Screen width screen.height Screen height
//window.innerWidth Removes the window width of the toolbar and scrollbar. Window. innerHeight Removes the window height of the toolbar and scrollbar
Copy the code

4.5 Loading Time

  • PerformanceTiming
  • DOMContentLoaded
  • FMP

4.5.1 Meaning of Phases

field meaning
navigationStart Initialize the page, the timestamp of the previous page’s Unload in the same browser context, or equal to the fetchStart value if there was no previous page’s unload
redirectStart The time when the first HTTP redirect occurs, with a jump and a codomain redirect, or 0 otherwise
redirectEnd The time when the last redirection is complete, otherwise 0
fetchStart The time when the browser is ready to retrieve the document using an HTTP request, before checking the cache
domainLookupStart The time when DNS domain name query starts. If there is a local cache or keep-alive, the time is 0
domainLookupEnd DNS Domain name End query time
connectStart The time when TCP starts to establish a connectionfetchStartValues are equal
secureConnectionStart The time when the HTTPS connection starts, or 0 if the connection is not secure
connectEnd The time when TCP completes the handshake, and if the connection is persistentfetchStartValues are equal
requestStart The time an HTTP request begins to read a real document, including from the local cache
requestEnd The time when an HTTP request to read a real document ends, including from the local cache
responseStart Returns the Unix millisecond timestamp when the browser receives the first byte from the server (or reads it from the local cache)
responseEnd Returns the Unix millisecond timestamp when the browser received (or read from the local cache, or read from a local resource) the last byte from the server
unloadEventStart The time stamp for the previous page’s Unload is 0 if there is none
unloadEventEnd withunloadEventStartThe corresponding return isunloadTimestamp of completion of function execution
domLoading Returns the timestamp when the DOM structure of the current web page began parsingdocument.readyStateBecomes Loading and will throwreadyStateChangeThe event
domInteractive Returns the timestamp when the DOM structure of the current page ends parsing and starts loading embedded resources.document.readyStatebecomeinteractiveAnd will throwreadyStateChangeEvent (note that only the DOM tree has been parsed and the resources in the page have not been loaded)
domContentLoadedEventStart Page domContentLoaded event occurred at the time
domContentLoadedEventEnd DomContentLoaded event script execution time,domReady time
domComplete When the DOM tree is parsed and the resources are ready,document.readyStatebecomecomplete. And will throwreadystatechangeThe event
loadEventStart The LOAD event is sent to the document, which is when the LOAD callback function starts executing
loadEventEnd The time when the load callback completes execution

4.5.2 Stage calculation

field describe calculation meaning
unload Previous page uninstallation time UnloadEventEnd – unloadEventStart
redirect Redirection Time RedirectEnd – redirectStart Redirection time
appCache Cache time consuming DomainLookupStart – fetchStart The time to read the cache
dns DNS Resolution Time DomainLookupEnd – domainLookupStart You can check whether the domain name resolution service is normal
tcp TCP Connection Time ConnectEnd – connectStart Duration of establishing a connection
ssl SSL connection time ConnectEnd – secureConnectionStart Indicates the data security connection establishment time
ttfb Time to First Byte(TTFB) Network request Time ResponseStart – requestStart TTFB is the number of milliseconds it takes to send a page request until the first byte of reply data is received
response Response data transmission time ResponseEnd – responseStart Check whether the network is normal
dom DOM Parsing Time DomInteractive – responseEnd Observe that the DOM structure is reasonable and that JS blocks page parsing
dcl DOMContentLoaded The event takes time DomContentLoadedEventEnd – domContentLoadedEventStart The DOMContentLoaded event is fired when the HTML document is fully loaded and parsed, without waiting for the stylesheet, image, and subframe to complete loading
resources Resource Loading Time DomComplete – domContentLoadedEventEnd You can observe whether the document flow is too large
domReady DOM stage rendering time DomContentLoadedEventEnd – fetchStart When the DOM tree and page resources have finished loadingdomContentLoadedThe event
First render time First render time responseEnd-fetchStart The time between loading the document and seeing the first frame of a non-empty image, also known as white screen time
First interaction time First interaction time domInteractive-fetchStart When DOM tree parsing is completed, document.readyState is interactive
The first packet takes time The first package time responseStart-domainLookupStart DNS resolves until the response is returned to the browser in the first byte
Page full load time Page full load time loadEventStart – fetchStart
onLoad OnLoad Event time LoadEventEnd – loadEventStart

4.5.3 Data Structure

{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590828364183"."userAgent": "chrome"."kind": "experience"."type": "timing"."connectTime": "0"."ttfbTime": "1"."responseTime": "1"."parseDOMTime": "80"."domContentLoadedTime": "0"."timeToInteractive": "88"."loadTime": "89"
}
Copy the code

4.5.4 implementation

import onload from ".. /util/onload";
import tracker from ".. /util/tracker";
import formatTime from ".. /util/formatTime";
import getLastEvent from ".. /util/getLastEvent";
import getSelector from ".. /util/getSelector";
export function timing() {
  onload(function () {
    setTimeout(() = > {
      const {
        fetchStart,
        connectStart,
        connectEnd,
        requestStart,
        responseStart,
        responseEnd,
        domLoading,
        domInteractive,
        domContentLoadedEventStart,
        domContentLoadedEventEnd,
        loadEventStart,
      } = performance.timing;
      tracker.send({
        kind: "experience".type: "timing".connectTime: connectEnd - connectStart, // The TCP connection takes time
        ttfbTime: responseStart - requestStart, //ttfb
        responseTime: responseEnd - responseStart, //Response Indicates the Response time
        parseDOMTime: loadEventStart - domLoading, //DOM parsing takes time
        domContentLoadedTime:
          domContentLoadedEventEnd - domContentLoadedEventStart, //DOMContentLoaded Event callback time
        timeToInteractive: domInteractive - fetchStart, // First interactive time
        loadTime: loadEventStart - fetchStart, // Full load time
      });
    }, 3000);
  });
}

Copy the code

4.6 Performance Specifications

  • PerformanceObserver. Observe the incoming parameters to the performance of the specified item type in the collection. When a performance item of the specified type is logged, the performance monitoring object’s callback function is called
  • entryType
  • paint-timing
  • event-timing
  • LCP
  • FMP
  • time-to-interactive
field describe note calculation
FP First Paint Includes any user – defined background drawing, which is the first time a pixel is drawn to the screen
FCP First Content Paint Is the time it takes the browser to render the first DOM to the screen, be it text, image, SVG, etc., which is essentially white screen time
FMP First Meaningful Paint Page meaningful content rendering time
LCP Largest Contentful Paint Represents the maximum page element loading time in viewPort
DCL (DomContentLoaded) The DOMContentLoaded event is fired when the HTML document is fully loaded and parsed, without waiting for the stylesheet, image, and subframe to complete loading
L (onLoad) This alarm is triggered when all dependent resources are loaded
TTI Time to Interactive Used to mark a point in time when the application has been visually rendered and can reliably respond to user input
FID First Input Delay The time between the user’s first interaction with the page (clicking a link, clicking a button, etc.) and the page’s response to the interaction

4.6.1 Data structure design

1. paint
{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590828364186"."userAgent": "chrome"."kind": "experience"."type": "paint"."firstPaint": "102"."firstContentPaint": "2130"."firstMeaningfulPaint": "2130"."largestContentfulPaint": "2130"
}
Copy the code
2. firstInputDelay
{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590828477284"."userAgent": "chrome"."kind": "experience"."type": "firstInputDelay"."inputDelay": "3"."duration": "8"."startTime": "4812.344999983907"."selector": "HTML BODY #container .content H1"
}
Copy the code

4.6.2 implementation

The key time node through the window. The performance. Timing acquisition

import tracker from ".. /utils/tracker";
import onload from ".. /utils/onload";
import getLastEvent from ".. /utils/getLastEvent";
import getSelector from ".. /utils/getSelector";

export function timing() {
  let FMP, LCP;
  // Add a performance item observer
  new PerformanceObserver((entryList, observer) = > {
    const perfEntries = entryList.getEntries();
    FMP = perfEntries[0];
    observer.disconnect(); // No more observation
  }).observe({ entryTypes: ["element"]});// Observe the meaningful elements in the page
  // Add a performance item observer
  new PerformanceObserver((entryList, observer) = > {
    const perfEntries = entryList.getEntries();
    const lastEntry = perfEntries[perfEntries.length - 1];
    LCP = lastEntry;
    observer.disconnect(); // No more observation
  }).observe({ entryTypes: ["largest-contentful-paint"]});// Look at the largest element in the page
  // Add a performance item observer
  new PerformanceObserver((entryList, observer) = > {
    const lastEvent = getLastEvent();
    const firstInput = entryList.getEntries()[0];
    if (firstInput) {
      // The time to start processing - the time to start clicking, the difference is the processing delay
      let inputDelay = firstInput.processingStart - firstInput.startTime;
      let duration = firstInput.duration; // Processing time
      if (inputDelay > 0 || duration > 0) {
        tracker.send({
          kind: "experience".// User experience metrics
          type: "firstInputDelay".// First input delay
          inputDelay: inputDelay ? formatTime(inputDelay) : 0.// The delay time
          duration: duration ? formatTime(duration) : 0.startTime: firstInput.startTime, // Start processing time
          selector: lastEvent
            ? getSelector(lastEvent.path || lastEvent.target)
            : ""}); } } observer.disconnect();// No more observation
  }).observe({ type: "first-input".buffered: true }); // First interaction

  // Start the page empty, wait until the page is rendered, then decide
  onload(function () {
    setTimeout(() = > {
      const {
        fetchStart,
        connectStart,
        connectEnd,
        requestStart,
        responseStart,
        responseEnd,
        domLoading,
        domInteractive,
        domContentLoadedEventStart,
        domContentLoadedEventEnd,
        loadEventStart,
      } = window.performance.timing;
      // Send time indicator
      tracker.send({
        kind: "experience".// User experience metrics
        type: "timing".// Count the time of each phase
        connectTime: connectEnd - connectStart, // The TCP connection takes time
        ttfbTime: responseStart - requestStart, // The arrival time of the first byte
        responseTime: responseEnd - responseStart, // response Indicates the response time
        parseDOMTime: loadEventStart - domLoading, // DOM parsing render time
        domContentLoadedTime:
          domContentLoadedEventEnd - domContentLoadedEventStart, // DOMContentLoaded Event callback time
        timeToInteractive: domInteractive - fetchStart, // First interactive time
        loadTime: loadEventStart - fetchStart, // Full load time
      });
      // Send performance indicators
      let FP = performance.getEntriesByName("first-paint") [0];
      let FCP = performance.getEntriesByName("first-contentful-paint") [0];
      console.log("FP", FP);
      console.log("FCP", FCP);
      console.log("FMP", FMP);
      console.log("LCP", LCP);
      tracker.send({
        kind: "experience".type: "paint".firstPaint: FP ? formatTime(FP.startTime) : 0.firstContentPaint: FCP ? formatTime(FCP.startTime) : 0.firstMeaningfulPaint: FMP ? formatTime(FMP.startTime) : 0.largestContentfulPaint: LCP
          ? formatTime(LCP.renderTime || LCP.loadTime)
          : 0}); },3000);
  });
}
Copy the code

4.7 caton

  • If the response time for a user interaction is greater than 100ms, the user will feel sluggish

4.7.1 Data design longTask

{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590828656781"."userAgent": "chrome"."kind": "experience"."type": "longTask"."eventType": "mouseover"."startTime": "9331"."duration": "200"."selector": "HTML BODY #container .content"
}
Copy the code

4.7.2 implementation

  • new PerformanceObserver
  • Entry. Duration > 100 If the duration is greater than 100ms, it is considered as a long task
  • Report data using requestIdleCallback
import tracker from ".. /util/tracker";
import formatTime from ".. /util/formatTime";
import getLastEvent from ".. /util/getLastEvent";
import getSelector from ".. /util/getSelector";
export function longTask() {
  new PerformanceObserver((list) = > {
    list.getEntries().forEach((entry) = > {
      if (entry.duration > 100) {
        let lastEvent = getLastEvent();
        requestIdleCallback(() = > {
          tracker.send({
            kind: "experience".type: "longTask".eventType: lastEvent.type,
            startTime: formatTime(entry.startTime), // Start time
            duration: formatTime(entry.duration), // The duration
            selector: lastEvent
              ? getSelector(lastEvent.path || lastEvent.target)
              : ""}); }); }}); }).observe({entryTypes: ["longtask"]}); }Copy the code

4.8 PV, UV, user stay time

4.8.1 Data Design Business

{
  "title": "Front-end monitoring system"."url": "http://localhost:8080/"."timestamp": "1590829304423"."userAgent": "chrome"."kind": "business"."type": "pv"."effectiveType": "4g"."rtt": "50"."screen": "2049x1152"
}
Copy the code

4.8.2 PV, UV, user stay time

PV(Page View) is the number of page views, UV(Unique visitor) user visits. PV as long as the page is visited once, UV multiple visits in the same day only once.

For the front end, as long as enter the page to report a PV on the line, UV statistics on the server to do, mainly to analyze the reported data to obtain UV statistics.

import tracker from ".. /util/tracker";
export function pv() {
  tracker.send({
    kind: "business".type: "pv".startTime: performance.now(),
    pageURL: getPageURL(),
    referrer: document.referrer,
    uuid: getUUID(),
  });
  let startTime = Date.now();
  window.addEventListener(
    "beforeunload".() = > {
      let stayTime = Date.now() - startTime;
      tracker.send({
        kind: "business".type: "stayTime",
        stayTime,
        pageURL: getPageURL(),
        uuid: getUUID(),
      });
    },
    false
  );
}
Copy the code

Extension problem

  1. Performance Monitoring Indicators
  2. How does the front end monitor performance
  3. What about online error monitoring
  4. How do you monitor memory leaks
  5. How does Node perform performance monitoring

1. Performance monitoring indicators

indicators The name of the explain
FP First-paint Renders the First time Represents the time between the browser’s request for the site and the screen rendering of the first pixel
FCP First-contentful-paint Renders the First content Represents the time when the browser renders the first content, which can be text, image, SVG element, etc., excluding the iframe and white background canvas element
SI Speed Index Indicates the Speed Index Indicates the speed at which web page content can be filled visually
LCP Largest Contentful Paint Maximum content Marks the time to render the maximum text or image
TTI Time to Interactive Indicates the Interactive Time The page loads from the start until the main subresource is rendered and responds quickly and reliably to user input
TBT Total Blocking Time Total Blocking Time Measure the total time between FCP and TTI, during which the main thread is blocked for too long to respond to input
FID First Input Delay Delay of initial Input An important user-centric measure of load responsiveness
CLS Cumulative Layout Shift Cumulative Layout offset It measures the maximum sequence of layout offset scores for all unexpected layout offsets that occur over the life of the page
DCL DOMContentLoaded The DOMContentLoaded event is fired after the initial HTML document has been fully loaded and parsed, without waiting for the stylesheet, image, and subframe to complete loading
L Load Check for a fully loaded page. The load event is triggered only after the HTML, CSS, JS, images and other resources of the page have been loaded

2. How to perform front-end performance monitoring

  • FP, FCP, LCP, CLS, FID, FMP are available through PerformanceObserver
  • You can obtain the TCP connection time, first byte arrival time, response response time, DOM parsing and rendering time, TTI, DCL, and L using performance. Timing
  • PerformanceObserver listens to longTask
const {
    fetchStart,
    connectStart,
    connectEnd,
    requestStart,
    responseStart,
    responseEnd,
    domLoading,
    domInteractive,
    domContentLoadedEventStart,
    domContentLoadedEventEnd,
    loadEventStart,
} = window.performance.timing;
const obj = {
    kind: "experience".// User experience metrics
    type: "timing".// Count the time of each phase
    dnsTime: domainLookupEnd - domainLookupStart, // DNS query time
    connectTime: connectEnd - connectStart, // The TCP connection takes time
    ttfbTime: responseStart - requestStart, // The arrival time of the first byte
    responseTime: responseEnd - responseStart, // response Indicates the response time
    parseDOMTime: loadEventStart - domLoading, // DOM parsing render time
    domContentLoadedTime:
      domContentLoadedEventEnd - domContentLoadedEventStart, // DOMContentLoaded Event callback time
    timeToInteractive: domInteractive - fetchStart, // First interactive time
    loadTime: loadEventStart - fetchStart, // Full load time
}
Copy the code

3. How to do online error monitoring

  • Resource load error window. The addEventListener (‘ error ‘) judge e. arget. SRC | | href
  • Js runtime error window.addeventListener (‘error’)
  • Promise abnormal window. AddEventListener (‘ unhandledrejection ‘)
  • Interface exception Overwrites the OPEN send method of XHR, monitors load, error, and abort, and reports the error

4. How to monitor memory leaks

  • The global variable
  • The forgotten timer
  • Out-of-dom references
  • closure

Monitoring memory leaks

  • window.performance.memory
  • The development phase
    • Browser Performance
    • PerformanceDog is available on mobile

5. How does Node perform performance monitoring

  1. Log monitoring Enables you to monitor the changes of exception logs and reflect the types and quantities of new exceptions. You can monitor PV and UV logs to know users’ usage habits and predict access peaks
  2. Response time Response time is also a point to monitor. Once a subsystem of the system is abnormal or performance bottlenecks will lead to a long response time of the system. Response times can be monitored on reverse proxies such as Nginx or by the application itself generating access logs
  3. Process monitoring Monitoring logs and response times are good indicators of the state of the system, but they assume that the system is running, so monitoring processes is a more critical task than the first two. Monitoring processes generally check the number of application processes running in the operating system. For example, for web applications with multi-process architecture, you need to check the number of working processes and raise an alarm if the number falls below the low estimate
  4. Disk Monitoring The disk monitoring function monitors the disk usage. Due to frequent logging, disk space is gradually used up. Set an upper limit on disk usage, which can cause problems for the system. If disk usage exceeds the alarm threshold, the server administrator should delog or clean up the disk
  5. Memory monitoring For Nodes, once there is a memory leak, it is not easy to detect. Monitor server memory usage. If the memory is only going up and not down, you must have a memory leak. Normal memory usage should be up and down, rising when the traffic is high and falling when the traffic is down. Monitoring memory exception times is also a good way to prevent system exceptions. If a memory exception suddenly occurs, you can also track which recent code changes caused the problem
  6. CPU usage Monitoring The CPU usage of the server is also an essential item. CPU usage can be monitored in user mode, kernel mode, and IOWait mode. If the CPU usage in user mode is high, the application on the server requires a large AMOUNT of CPU overhead. If the kernel CPU usage is high, the server needs to spend a lot of time on process scheduling or system calls. IOWait usage indicates that the CPU waits for disk I/O operations. In the CPU usage, the user mode is less than 70%, the kernel mode is less than 35%, and the overall CPU usage is less than 70%, which are within the normal range. Monitoring CPU usage helps you analyze the status of your application in real business. Reasonable setting of monitoring threshold can give a good warning
  7. CPU Load Monitoring CPU load is also called average CPU load. It is used to describe the current busy degree of the operating system, and is simply understood as the average number of CPU tasks in use and waiting to use CPU in a unit of time. It has three metrics, namely 1-minute average load, 5-minute average load, and 15-minute average load. If the CPU load is too high, the number of processes is too high, which may be reflected in node when the process module repeatedly starts new processes. Monitoring this value can prevent accidents
  8. I/O Load I/O load refers to disk I/O. It reflects the read and write status on the disk. For node applications, which are mainly network oriented services, it is unlikely that the I/O load is too high. Most OF the I/O pressure comes from the database. Regardless of whether the Node process works with the same server as a database or other I/ O-intensive application, we should monitor this value for unexpected situations
  9. Network monitoringAlthough the priority of network traffic monitoring is not as high as that of the preceding items, you still need to monitor the traffic and set a traffic upper limit. Even if your app suddenly becomes popular with users, you can get a sense of how effective your site’s advertising is when traffic skyrockets. Once the traffic exceeds the warning level, the developer should find out why the traffic is increasing. For normal growth, you should evaluate whether to add hardware to serve more users. The two main indicators of network traffic monitoring are inbound traffic and outbound traffic
    • In addition to these mandatory metrics, an application should also provide a mechanism to feedback its own state information. External monitoring will continuously call the application’s feedback interface to check its health status.
    • DNS Monitoring DNS is the basis of network applications. Most external service products depend on domain names. It is not uncommon for DNS failures to cause extensive product impact. The DNS service is usually stable and easy to ignore, but when it fails, it can be unprecedented. To ensure product stability, you also need to monitor domain name and DNS status.