Skip to content
Created: May 1, 2019

1. Overview and core value of front-end monitoring ​

Front-end monitoring is the "eyes" to ensure product quality.It can help you find bugs before users complain and quantify performance bottlenecks before your boss questions them.

2. Three Core Dimensions of Monitoring (What to Monitor?) ​

A complete front-end monitoring system usually includes the following three aspects:

🛡️ Stability monitoring (Stability / Error) ​

  • JS Error: An error occurred during runtime (TypeError, ReferenceError, etc.).
  • Resource loading error: Image, CSS, Script loading failed (usually 404).
  • API request error: The interface returns 4xx/5xx, or "successful but error" in business logic (such as {code: -1, msg: 'error'}).
  • White screen detection: The key DOM node of the page is missing, causing the user to see a white screen. This is the highest priority fatal failure.

🚀Performance Monitoring (Performance) ​

  • Loading speed: How long does it take for the page to be refreshed?How long does it take to interact?
  • Interface time consumption: The response time of key business interfaces.
  • Static resources: It is mainly time-consuming to load large images and large JS files.

👥 User Behavior Monitoring (User Behavior) ​

  • PV/UV: Basic visit data.
  • User path: Which page the user clicked on and where they jumped to.
  • Click heat map: Where users like to click most.
  • Session Replay: This is an artifact for troubleshooting bugs.Use technical means (such as rrweb) to record user operation videos to restore the real scene when the bug occurs.

3. Key Performance Indicators (Core Web Vitals) ​

The three Core Web Vitals are LCP, INP and CLS, normally assessed at the 75th percentile of real-user visits. FCP is a supplementary loading metric.

MetricFull nameMeaningWhat does it measure?Good threshold
LCPLargest Contentful PaintLargest contentful paintWhen the largest eligible image or text block in the viewport appears.≤ 2.5s
INPInteraction to Next PaintInteraction to next paintOverall responsiveness to page interactions.≤ 200ms
CLSCumulative Layout ShiftCumulative layout shiftVisual stability across the page lifecycle; a unitless score.≤ 0.1
FCP (supplementary)First Contentful PaintFirst contentful paintWhen content first paints; business readiness is not guaranteed.≤ 1.8s

4. Tool selection plan ​

Depending on team size and budget, there are typically three options:

💎 Option A: SaaS business service (the most worry-free, but expensive) ​

Suitable for small and medium-sized teams or rapid iteration periods, where money buys time.

  • Sentry: The strongest in the world.The error tracking capability is extremely strong, it supports SourceMap to restore the code, and the current performance monitoring is also very good.
  • LogRocket: focuses on session playback. You can watch how users make mistakes like watching a movie, and the experience is excellent.
  • Alibaba Cloud ARMS / Tencent Cloud RUM: Solution from a major domestic manufacturer, with good compliance and fast network access.

🛠️ Option B: Self-research/Built based on open source (cost controllable, data private) ​

Suitable for large factories or teams with high data privacy requirements.

  • Web-Tracing: An open source project by domestic developers with relatively complete functions.
  • Prometheus + Grafana: A commonly used monitoring solution on the backend. The frontend reports data through the hidden SDK, and Grafana makes the visualization panel.
  • Sentry (Self-hosted): Sentry provides a private deployment version, but the maintenance cost (server resources, database) is higher.

📦 Plan C: Simple burying point (lightweight) ​

  • Google Analytics (GA4): Free, mainly looks at traffic and simple performance data, and has weak bug checking capabilities.
  • Lighthouse (local): It is not real-time monitoring, but suitable for optimization of running scores during the development phase.

5. Core technology implementation and difficulties ​

5.1 Implementation plan of white screen monitoring ​

✅ 1. What is a white screen? ​

A white screen means that after the page is loaded, the user sees "nothing is rendered" for a few seconds. Common reasons:

  • JS error causes root node not to be mounted
  • Resource loading failed (CSS/JS)
  • Backend returns empty HTML
  • Routing jump exception (SPA)
  • Rendering blocked by long task
  • Third party script stuck

The core of white screen reporting: It was found that the user saw a "full white" screen and contextual information was recorded.

✅ 2. 3 practical solutions for white screen detection (sorted by reliability) ​

Option 1: Critical DOM Detection (Recommended) ​

Suitable for pages with an explicit business readiness marker; calibrate for content and loading states.

Principle: Determine whether key content is successfully rendered on the first screen (main container, key nodes, LCP elements, etc.)

✔ Detection example ​
js
(function () {
  const TIMEOUT = 5000;
  let lcp;
  let observer;

  if (typeof PerformanceObserver !== 'undefined' &&
      PerformanceObserver.supportedEntryTypes?.includes('largest-contentful-paint')) {
    observer = new PerformanceObserver(list => {
      for (const entry of list.getEntries()) lcp = entry.startTime;
    });
    observer.observe({ type: 'largest-contentful-paint', buffered: true });
  }

  setTimeout(() => {
    if (document.visibilityState !== 'visible') {
      observer?.disconnect();
      return;
    }

    const root = document.getElementById('app') || document.getElementById('root');
    // Mark meaningful business content, including empty or image-only views.
    const content = root?.querySelector('[data-page-ready="true"]');
    const rect = content?.getBoundingClientRect();
    const ready = rect && rect.width > 0 && rect.height > 0;

    if (!ready) {
      navigator.sendBeacon('/monitor/white-screen', JSON.stringify({
        type: 'suspected-white-screen',
        url: location.href,
        timestamp: Date.now(),
        performance: {
          fcp: performance.getEntriesByName('first-contentful-paint')[0]?.startTime ?? null,
          lcp: lcp ?? null
        }
      }));
    }
    observer?.disconnect();
  }, TIMEOUT);
})();

Set data-page-ready="true" on meaningful business content. A missing marker after timeout indicates a suspected failure requiring loading and error context. LCP cannot prove continued page health. Check SPA route changes separately; the original LCP is not a metric for each transition.

Option 2: Pixel sampling detection (more stringent, but consumes performance) ​

canvas.drawImage() cannot draw document.body directly. Obtain an image through a supported screenshot or DOM rendering mechanism first; cross-origin images can also prevent pixel readback.

For a readable screenshot, divide the sum of RGB channels by three times the pixel count for a 0–255 average. Sample multiple areas, exclude transparent pixels and account for dark themes, empty states and loading placeholders; a 10×10 top-left sample cannot classify the whole screen.

Screenshot acquisition and thresholds require separate implementation and validation, so no direct-body screenshot code is presented here.drawImage parameters.

Option 3: Timeout + No change in DOM (lightweight fallback) ​

An unchanged node count does not establish a white screen: static pages, SSR and text updates may preserve it. Record the count and readiness marker as diagnostics rather than definitive failure signals.

✅ 3. Data format for white screen reporting (recommendation) ​

Unified structure facilitates analysis:

json
{
  "type": "white-screen",
  "url": "https://xxx.com/page",
  "timestamp": 1710000000000,
  "ua": "Mozilla/5.0 ...",
  "domCount": 4,
  "fcp": 2200,
  "lcp": 0,
  "stack": "Error stack if available",
  "network": {
    "rtt": 50,
    "downlink": 4
  },
  "htmlSample": "<html>..."
}

✅ 4. How to reduce false alarms? ​

1. Check if there is LCP ​

LCP shows that eligible content was painted, but later routing or rendering can fail. Collect it with PerformanceObserver and do not use it alone to exclude failure.

2. Check whether there is a skeleton (skeleton screen) ​

Treat skeletons as a loading state and check business content after a deadline; permanently skipping them hides stuck loading.

3. Check whether the user actively switches tabs ​

If the page is backgrounded, white screen detection should be skipped:

js
document.visibilityState === "visible"
4. Region + device aggregation ​

Higher failure rates on low-end devices may reflect slow loading, main-thread blocking or compatibility problems; investigate with data.

✅ 5. White screen monitoring dashboard (indicator suggestions) ​

You can do 3 core indicators in Grafana/Sentry/Datadog:

1. White screen rate (main indicator) ​

白屏次数 / PV
2. Missing LCP rate (separate unsupported APIs, hidden pages and collection failures) ​
3. White screen distribution ​
  • Terminal: Android / iOS / Desktop
  • Region: Province/Country
  • Network: 4G/WiFi
  • Page: URL pattern

This can quickly locate specific scenarios.

White screen diagnostic process

  1. Look at RUM data: FCP/LCP/INP and geographical/device distribution to determine if there is a general or individual device/region issue.
  2. Playback/filmstrip: Use Lighthouse lab filmstrip or RUM video/playback to find out "when the largest element occurs".(If LCP is always a large picture → optimize the picture) ([web.dev][3])
  3. Check the network panel: whether the resource is blocked (CSS/JS/Fonts) or the third party is slow.
  4. Check the main thread: whether it is blocked by a long task (causing rendering to be delayed).
  5. Implementation strategy (fastest path): Ensure that the first screen HTML can be directly rendered + preload key resources + asynchronous non-critical JS.

Tool recommendations (monitoring + local debugging)

  • RUM/Monitoring: Sentry / Datadog RUM / NewRelic Browser / Self-built collection + Grafana
  • Local/CI Test: Lighthouse (or Lighthouse CI) + PageSpeed Insights + WebPageTest (filmstrip)
  • Diagnosis: Chrome DevTools (Performance panel + Lighthouse) + web-vitals (escalation) ([Chrome for Developers][2])

5.2 Error capturing and reporting ​

Cross-domain js execution error capture ​

Can only capture errors but cannot get specific information

  1. Add the crossorigin attribute to the script tag (done on the client side)
  2. Set js resource response header Access-Control-Allow-Origin: * (This can be * or domain name. It needs to be done on the server side)
Error reporting ​
  1. Report using ajax communication method (this method is generally not used)
  2. Use Image object to report (such as Google's gaa, domestic cnzz all report in image mode)
  3. When monitoring requests for reporting, you can rewrite the xmlHttpRequest method and rewrite the send function. After executing the report, use the old send function call to execute the sending request.
js
export function injectXHR() {
    let XMLHttpRequest = window.XMLHttpRequest;
    let oldOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
        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({//未捕获的promise错误
                    kind: 'stability',//稳定性指标
                    type: 'xhr',//xhr
                    eventType: type,//load error abort
                    pathname: this.logData.url,//接口的url地址
                    status: status + "-" + statusText,
                    duration: "" + duration,//接口耗时
                    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);
    };
}

// It's simpler to use the image method, and you can easily report it in one line

js
(new Image()).src="http://xxx.com/abc?r=yyy"

5.3 Performance data collection ​

  1. Monitoring and Regression Prevention* Add Lighthouse or PSI checks (focus on LCP/FCP/INP regressions) in CI/PR and verify with RUM data after release.
  2. PerformanceTiming object contains latency-related performance information
  3. The PerformanceObserver.observe method is used to observe the collection of performance entry types specified in the passed parameters.When recording a performance entry of a specified type, the callback function of the performance monitoring object will be called.
js
// 安装:npm i web-vitals
import {onLCP, onFCP, onCLS, onINP} from 'web-vitals';

function sendMetric(name, value, extra = {}) {
  navigator.sendBeacon('/rum/metric', JSON.stringify({name, value, extra, url: location.href, ts: Date.now()}));
}

onLCP(metric => sendMetric('LCP', metric.value));
onFCP(metric => sendMetric('FCP', metric.value));
onCLS(metric => sendMetric('CLS', metric.value));
onINP(metric => sendMetric('INP', metric.value));

The example uses web-vitals APIs onLCP, onFCP, onCLS and onINP. Pin the version and check exports; the server must still aggregate real-user metrics correctly.Official usage. Native test LCP (simple example)

js
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // entry.startTime 是 LCP 的时间(ms)
    console.log('LCP candidate', entry.startTime, entry);
    navigator.sendBeacon('/rum/metric', JSON.stringify({name:'LCP', value: entry.startTime}));
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

(Note: Page visibility and final candidates are combined to determine the final LCP, the actual library handles these details.) ([web.dev])

5.4 Difficulties and techniques in implementation of solutions (SourceMap, sampling, filtering) ​

If you are ready to start monitoring, pay attention to the following pitfalls:

  1. SourceMap Security Issues:

    • Errors reported online are usually compressed code (such as a.js:1:503), which is incomprehensible.
    • Solution: You need to upload the .map file to the monitoring platform (such as Sentry) during the build process (CI/CD), but definitely not deploy it to a public server, otherwise the source code will be leaked.
  2. Massive log peak shaving:

    • If a bug causes an infinite loop of error reports, tens of thousands of logs in an instant will overwhelm the server or exhaust the SaaS quota.
    • Solution: The front-end SDK must do Sampling and Throttle.For example: the same error is only reported once within 1 second, or only 10% of the performance data is collected.
  3. Meaningless error:

    • Script error. (cross-domain scripting error) or error injected by browser plug-in.
    • Solution: Configure filtering rules (Ignore List) to ignore script errors and common plug-in errors for non-business domain names.

6. Summary and implementation route ​

💡 Recommended starting route:

  1. Phase 1 (stop bleeding): Access Sentry (free version or private deployment), focusing on monitoring JS error and white screen.Make sure the program doesn't crash first.
  2. Phase 2 (Optimization): Introduce the web-vitals library, report LCP and INP data, and combine with the performance panel to optimize the first screen speed.
  3. The third stage (insight): Combined with rrweb to realize user operation playback and solve those weird bugs that "I can't reproduce locally".

7. References and further reading ​

Web Vitals ​

  • TTFB (time to first byte) refers to the time it takes for the browser to initiate the first request and return the first byte of data. This time includes network request time and back-end processing time.
  • FP (First Paint) The first draw includes any user-defined background drawing. It is the moment when the first pixel is drawn to the screen.
  • FCP (First Content Paint) (First Content Paint) The first content paint is the time when the browser renders the first DOM to the screen. It can be the time for any text, image, SVG, etc.
  • FMP (First Meaningful paint) First meaningful paint is a measure of page usability
  • INP (Interaction to Next Paint): reflects responsiveness to clicks, taps and keyboard interactions over the page lifecycle, including input delay, processing and presentation delay.
  • LCP (Largest Contentful Paint) Represents the loading time of the largest page element in the viewport. 2.5s Within 2.5s to 4s is good, but needs to be optimized.
  • DCL (DomContentLoaded) (DOM loading completed) When the HTML document is fully loaded and parsed, the DOMContentLoaded event is triggered without waiting for the completion of loading of style sheets, images, and subframes.
  • L (onLoad) will only be triggered after all dependent resources have been loaded.
  • TTI (Time to Interactive) is used to mark the point in time when the application has been visually rendered and can reliably respond to user input.
  • FID (First Input Delay): the wait from the first interaction to event processing starting. This historical Core Web Vital has been replaced by INP.
  • TBT (Total blocking time) the cumulative blocking time of the main thread
  • CLS (Cumulative Layout Shift) is a unitless score: ≤ 0.1 is good; > 0.1 and ≤ 0.25 needs improvement.Metric definition.
  • Stuttering: long tasks exceeding 50ms.If the response time to respond to user interaction is greater than 100ms, the user will feel stuck.
  • paint timing