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
- Performance Monitoring Indicators
- How does the front end monitor performance
- What about online error monitoring
- How do you monitor memory leaks
- 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
- The front-end buried point
- The data reported
- Processing the summary
- Visual presentation
- 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 connectionfetchStart Values 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 persistentfetchStart Values 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 | withunloadEventStart The corresponding return isunload Timestamp of completion of function execution |
domLoading | Returns the timestamp when the DOM structure of the current web page began parsingdocument.readyState Becomes Loading and will throwreadyStateChange The event |
domInteractive | Returns the timestamp when the DOM structure of the current page ends parsing and starts loading embedded resources.document.readyState becomeinteractive And will throwreadyStateChange Event (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.readyState becomecomplete . And will throwreadystatechange The 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 loadingdomContentLoaded The 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
- Performance Monitoring Indicators
- How does the front end monitor performance
- What about online error monitoring
- How do you monitor memory leaks
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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.