How to Build an Efficient Front‑End Monitoring Data Collection System

This article explains why front‑end monitoring is essential for user experience, outlines the key data types to collect, and provides practical AOP‑based implementations for route changes, JavaScript errors, performance metrics, resource failures, API calls, and reliable log reporting.

Mafengwo Technology
Mafengwo Technology
Mafengwo Technology
How to Build an Efficient Front‑End Monitoring Data Collection System

Front‑End Monitoring Data Collection

As business grows, front‑end reliability directly impacts user experience, making monitoring essential. Building a monitoring platform involves data collection, instrumentation, processing, alerting, and application.

What to Collect

We focus on two data categories: user‑experience metrics (first‑paint, load times, performance) and operational alerts (resource errors, API response times). The main collection points are:

Route changes (href, hashchange, pushState)

JavaScript errors

Performance via window.performance

Resource errors

API requests

Log reporting

Route Switching

Single‑page applications use routers (vue‑router, react‑router). Two mechanisms: hash and History API. For href, report an “enter page” event.

Hashchange detection example:

window.addEventListener('hashchange', function () {
    // report [enter page] event
}, true)

History API can be wrapped with AOP to dispatch custom events on pushState/replaceState.

function aop(type) {
    var source = window.history[type];
    return function () {
        var event = new Event(type);
        event.arguments = arguments;
        window.dispatchEvent(event);
        var rewrite = source.apply(this, arguments);
        return rewrite;
    };
}
window.history.pushState = aop('pushState');
window.history.replaceState = aop('replaceState');
window.addEventListener('pushState', function () {
    // report [enter page] event
}, true);
window.addEventListener('replaceState', function () {
    // report [enter page] event
}, true);

JavaScript Errors

Use window.onerror for general errors; window.addEventListener('error') is not recommended because it lacks stack information. For unhandled promise rejections:

window.addEventListener('unhandledrejection', function (e) {
    var reg_url = /\(([^)]*)\)/;
    var fileMsg = e.reason.stack.split('
')[1].match(reg_url)[1];
    var fileArr = fileMsg.split(':');
    var lineno = fileArr[fileArr.length - 2];
    var colno = fileArr[fileArr.length - 1];
    var url = fileMsg.slice(0, -lineno.length - colno.length - 2);
    var msg = e.reason.message;
    // report [js error] event
}, true);

Common issues include “Script error.” caused by cross‑origin scripts; solve with crossorigin attributes in Webpack. SourceMap handling is discussed.

Performance

After onload, read window.performance for metrics such as timing and memory.

Resource Errors

Capture resource loading failures via a global error listener.

window.addEventListener('error', function (e) {
    var target = e.target || e.srcElement;
    if (target instanceof HTMLScriptElement) {
        // report [resource error] event
    }
}, true);

API Monitoring

Wrap XMLHttpRequest and fetch using AOP to record method, URL, duration, status and report.

var xhr = window.XMLHttpRequest;
var _open = xhr.prototype.open;
var _send = xhr.prototype.send;
var attr = {};
var openReplacement = function (method, url) {
    attr.duration = new Date().getTime();
    _open.apply(this, arguments);
};
var sendReplacement = function () {
    methods.addEvent(this, 'readystatechange', function (attr) {
        attr.status = this.status;
        attr.duration = new Date().getTime() - attr.duration;
        // report [API] event
    }.bind(this, JSON.parse(JSON.stringify(attr))));
    _send.apply(this, arguments);
};
xhr.prototype.open = openReplacement;
xhr.prototype.send = sendReplacement;

var _fetch = window.fetch;
window.fetch = function () {
    var attr = {
        method: arguments[1] && arguments[1].method,
        url: arguments[0],
        duration: new Date().getTime()
    };
    return _fetch.apply(this, arguments).then(function (res) {
        attr.status = res.status;
        attr.duration = new Date().getTime() - attr.duration;
        // report [API] event
        return res;
    });
};

Log Reporting

Use navigator.sendBeacon for reliable transmission during page unload, falling back to an Image request when unsupported.

window.navigator.sendBeacon('api_endpoint', 'data');
var img = new Image();
img.src = API + '?' + 'data';

Prefer sendBeacon → img.src to minimize packet loss.

Conclusion

Accurate and timely front‑end data collection is crucial for a monitoring platform. The article shares MaFengWo’s practices and notes that the code snippets are illustrative and need production‑grade robustness and compatibility.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendMonitoringdata collectionJavaScriptAOPerror tracking
Mafengwo Technology
Written by

Mafengwo Technology

External communication platform of the Mafengwo Technology team, regularly sharing articles on advanced tech practices, tech exchange events, and recruitment.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.