How to Build a Comprehensive Front-End Performance Monitoring System

This article explains how to create a front‑end monitoring client that captures global JavaScript errors, tracks resource loading and page performance metrics, intercepts AJAX and fetch requests, gathers PV/UV statistics, and reports data using various strategies such as image beacons, POST, and IndexedDB storage.

Ziru Technology
Ziru Technology
Ziru Technology
How to Build a Comprehensive Front-End Performance Monitoring System

Introduction

Page performance optimization is essential for front‑end development, especially as pages become larger and interactions more complex. A continuous front‑end monitoring system helps quickly locate performance bottlenecks and guide developers to optimize.

Error Capture

The most basic part of a monitoring system is global error capture. By registering a global window.onerror handler you can obtain the error message, source file, line, column and the Error object.

window.onerror = function(message, source, lineno, colno, error) {
    // handle error
};

Static resource loading errors (JS, CSS, images, video, audio) can be caught with:

window.addEventListener('error', event => {
    // errorTarget = event.target
}, true);

Promise rejections are captured via unhandledrejection:

window.addEventListener('unhandledrejection', event => {
    // event.reason contains the rejection reason
});

Note that unhandledrejection has poor compatibility on many platforms (see compatibility chart).

Resource Monitoring

Beyond error counting, the loading speed of resources must be monitored. The Performance API’s performance.getEntries() returns detailed HTTP request information, including initiatorType and duration. Visualizing these durations helps identify slow resources.

Page Performance Monitoring

Performance timing data can be obtained from performance.timing. Key metrics include DNS lookup time, TCP connection time, TTFB, DOM parsing time, request time, and page load time.

DNS lookup: domainLookupEnd - domainLookupStart TCP connection: connectEnd - connectStart TTFB: responseStart - navigationStart DOM parsing: domComplete - responseEnd Request time: responseEnd - requestStart Page load:

loadEventEnd - navigationStart

AJAX Request Interception

To monitor AJAX errors, intercept the native XMLHttpRequest methods. The example below shows a simple proxy that records request URL, method, start time and later calculates load time.

window._ahrealxhr = window._ahrealxhr || XMLHttpRequest;
XMLHttpRequest = function () {
    this.xhr = new window._ahrealxhr();
    // proxy properties and methods
    for (var attr in this.xhr) {
        var type = typeof this.xhr[attr];
        if (type === 'function') {
            this[attr] = hookfun(attr);
        } else {
            Object.defineProperty(this, attr, {
                get: getFactory(attr),
                set: setFactory(attr)
            });
        }
    }
};

In open you can filter URLs and store the start time:

open([method, url], xhr) {
    if (options.filterURL.some(filter => url.includes(filter))) return;
    currentAjax.push({ url, method, startTime: new Date().getTime(), xhr });
}

The onreadystatechange and onload events are used to calculate the total request duration and report non‑2xx responses as errors.

onreadystatechange(xhr) {
    if (xhr.readyState !== 4) return;
    // calculate endTime, loadTime, and report if status >= 400
}

Fetch requests are intercepted by wrapping window.fetch and using then / catch to report non‑ok responses.

let _oldFetch = window.fetch;
window.fetch = function () {
    return _oldFetch.apply(this, arguments).then(res => {
        if (!res.ok) {
            // report error
        }
        return res;
    }).catch(error => {
        // report network error
        throw error;
    });
};

Framework Exception Interception

Modern frameworks provide global error hooks. For Vue use Vue.config.errorHandler, for React use componentDidCatch in an Error Boundary. These handlers can forward errors to the same reporting pipeline.

PV/UV Statistics

Page view (PV) and unique visitor (UV) metrics are collected together with performance data. Session storage can store a per‑session UID, while local storage with an expiration date tracks daily UVs.

function markSessionUserId() {
    let sessionUserId = sessionStorage.getItem('zr_monitor_session_uid') || '';
    if (sessionUserId) {
        return { isFirstIn: false, uid: sessionUserId };
    } else {
        sessionUserId = uuid();
        sessionStorage.setItem('zr_monitor_session_uid', sessionUserId);
        return { isFirstIn: true, uid: sessionUserId };
    }
}

Reporting Strategies

Collected data must be sent to a server. Common methods include:

Dynamic Image requests (GET with query string).

HTTP HEAD requests.

POST requests using XMLHttpRequest or fetch.

Beacon API ( navigator.sendBeacon) for unload‑time reporting.

For non‑urgent data, store locally (LocalStorage, IndexedDB) and batch‑upload later. IndexedDB offers larger capacity and transactional operations.

function saveOfflineData(data) {
    return new Promise((resolve, reject) => {
        let request = db.transaction('zr_offline_data', 'readwrite')
                         .objectStore('zr_offline_data')
                         .add(data);
        request.onerror = reject;
        request.onsuccess = e => resolve(e.target.result);
    });
}

Conclusion

This article outlines the core ideas for building a front‑end monitoring client, covering error capture, resource and performance monitoring, AJAX and fetch interception, framework hooks, PV/UV tracking, and various reporting mechanisms. Further enhancements can be added based on specific project needs.

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.

ajaxIndexedDBbeaconerror-handlingresource-loggingperformance-monitoring
Ziru Technology
Written by

Ziru Technology

Ziru Official Tech Account

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.