Mastering Front-End Event Tracking: From Data Collection to Performance Metrics

This article explains front‑end event tracking fundamentals, compares passive, code‑based, and SDK solutions, outlines common event attributes and types, details performance data collection via the Performance API, describes error capture methods, and presents reliable data reporting techniques using Beacon and image fallbacks.

ELab Team
ELab Team
ELab Team
Mastering Front-End Event Tracking: From Data Collection to Performance Metrics

Event Tracking Data Collection Scheme

What is Event Tracking

Event tracking, also known as event tracking, is a technique that captures, processes, and sends specific user behaviors or business processes for analysis.

It is the basis for product data analysis, used for recommendation feedback, user behavior monitoring, new feature or operation activity statistics, and more.

Event tracking includes two important concepts: event and param.

Event : what happens in the application, e.g., user actions, system events, or errors. Example events: enter_page, leave_page.

Param : attributes that describe user segmentation, e.g., language preference or location. Example for an "enter_exercise" event: enter_from, class_id.

Value : the concrete value of a param, e.g., enter_from: home, system.

Main Solutions

Passive (full) tracking: uses browser or app listeners to collect page views, clicks, etc. Advantages: simple integration, low intrusion, almost complete collection. Disadvantages: high noise, cannot customize specific events or attributes, limited information for data analysts.

Code tracking: developers add custom listeners in code. Advantages: precise event identification, rich business attributes, flexible trigger definitions, easier for analysts. Disadvantages: high workload, invasive, harder maintenance.

Tracking SDK: SDK exposes reporting APIs, making developers unaware of the collection process. Advantages: combines benefits of passive and code tracking. Disadvantages: not listed.

Common Event Attributes

Front‑end usually records events at the page level. Typical attributes include:

uid – user ID (or anonymous identifier if not logged in)

url – current page URL

eventTime – timestamp of event trigger

localTime – user local time in YYYY-MM-DD HH:mm:ss format

deviceType – device type (apple, samsung, chrome, etc.)

deviceId – device identifier

osType – operating system (windows, macos, ios, android)

osVersion – OS version

appVersion – application version

appId – application ID

extra – custom serialized data, stable structure

Common Event Types

Page stay – reported on page switch or unload, records previous page dwell time.

pv – page view, reported on page entry; counts page visits (uv can be derived from deviceId).

Interaction – reported when user interaction occurs (click, long press, etc.).

Logic – reported when logical conditions are met (login, navigation, etc.).

Performance Data Collection Scheme

Most performance metrics come from the window.performance API.

Performance.timing

Key timing parameters and their meanings include connectEnd, connectStart, domComplete, domContentLoadedEventEnd, domContentLoadedEventStart, domInteractive, domLoading, domainLookupEnd, domainLookupStart, fetchStart, loadEventEnd, loadEventStart, navigationStart, redirectEnd, redirectStart, requestStart, responseEnd, responseStart, secureConnectionStart, unloadEventEnd, and unloadEventStart.

Common Performance Metrics

FP – First Paint, reflects white‑screen time.

FCP – First Contentful Paint, first time content appears.

FMP – First Meaningful Paint, first time meaningful content is rendered.

TTI – Time To Interactive, time until the page is fully interactive.

FID – First Input Delay, delay of the first user interaction.

MPFID – Max Potential First Input Delay.

LOAD – total page load time (load event).

FP

FP indicates white‑screen duration and can be obtained via performance.getEntriesByType('paint') and the PerformancePaintTiming API.

FCP

FCP is the time when the first content is rendered, obtained similarly with name first-contentful-paint.

FMP

FMP is the time when the page’s main content is fully rendered; it can be approximated by the point of maximum layout shift using MutationObserver.

TTI

TTI is the time from page load start until the page meets three conditions: visible content displayed, event listeners for visible elements are registered, and event handlers start within 50 ms after an event.

Page shows useful content.

Event listeners for visible elements are registered.

Handlers start within 50 ms after an event.

Resource Loading Metrics

window.performance.getEntriesByType('resource')

returns performance data for each loaded resource (js, css, img, etc.).

Typical resource types: script, link, img, css, xmlhttprequest, beacon, fetch, other.

Key resource parameters include connectEnd, connectStart, decodedBodySize, domainLookupEnd, domainLookupStart, duration, encodedBodySize, entryType, fetchStart, initiatorType, name, nextHopProtocol, redirectEnd, redirectStart, requestStart, responseEnd, responseStart, secureConnectionStart, serverTiming, startTime, transferSize, workerStart.

Other Metric Calculations

DNS query time = domainLookupEnd - domainLookupStart

TCP connection time = connectEnd - connectStart

SSL connection time = connectEnd - secureConnectionStart

TTFB = responseStart - requestStart

Content transfer = responseEnd - responseStart

DOM parsing = domInteractive - responseEnd

Resource loading = loadEventStart - domContentLoadedEventEnd

First byte = responseStart - fetchStart

DOM ready = domContentLoadedEventEnd - fetchStart

Redirect time = redirectEnd - redirectStart

DOM render = domComplete - domLoading

Load = loadEventEnd - navigationStart

Unload = unloadEventEnd - unloadEventStart

Request time = responseEnd - requestStart

White screen = domLoading - navigationStart

Error Data Collection Scheme

Three types of errors can be captured:

Resource loading errors – captured with addEventListener('error', callback, true) during the capture phase.

JavaScript execution errors – captured with window.onerror.

Promise rejections – captured with addEventListener('unhandledrejection', callback), though line/column info is unavailable.

Cross‑origin script errors appear as "Script Error." To obtain details, add crossorigin="anonymous" to script tags and configure CORS on the server (Access‑Control‑Allow‑Origin: *).

// capture resource loading errors
addEventListener('error', e => {
    const target = e.target
    if (target != window) {
        monitor.errors.push({
            type: target.localName,
            url: target.src || target.href,
            msg: (target.src || target.href) + ' is load error',
            time: Date.now()
        })
    }
}, true)

// capture js errors
window.onerror = function(msg, url, row, col, error) {
    monitor.errors.push({
        type: 'javascript',
        row: row,
        col: col,
        msg: error && error.stack ? error.stack : msg,
        url: url,
        time: Date.now()
    })
}

// capture promise errors (no line info)
addEventListener('unhandledrejection', e => {
    monitor.errors.push({
        type: 'promise',
        msg: (e.reason && e.reason.msg) || e.reason || '',
        time: Date.now()
    })
})

Data Reporting Scheme

Two concerns: sharing a domain limits concurrent requests, and browsers ignore asynchronous Ajax during unload, requiring synchronous requests that slow navigation.

Beacon

Beacon API sends asynchronous non‑blocking POST requests without waiting for a response, and works before unload.

Uses HTTP POST.

No response required. navigator.sendBeacon(url, data); Data can be ArrayBufferView, Blob, DOMString, or FormData. The method returns true if queued.

Server must accept POST, handle CORS, and use a CORS‑safelisted content‑type (application/x‑www‑form‑urlencoded, multipart/form‑data, or text/plain).

type ContentType = 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain';

const serilizeParams = (params: object) => {
    return window.btoa(JSON.stringify(params))
}

function sendBeacon(url: string, params: object) {
  const formData = new FormData()
  formData.append('params', serilizeParams(params))
  navigator.sendBeacon(url, formData)
}

Image

As a fallback, an invisible image can be used to send GET requests before unload.

function sendImage(url: string, params: object) {
  const img = new Image()
  img.style.display = 'none'
  const removeImage = function() {
    img.parentNode.removeChild(img)
  }
  img.onload = removeImage
  img.onerror = removeImage
  img.src = `${url}?params=${serilizeParams(params)}`
  document.body.appendChild(img)
}

Be aware of URL length limits (HTTP 414) when using the image method.

Compatibility Strategy

Prefer Beacon; fall back to Image.

function sendLog(url: string, params: object) {
    if (navigator.sendBeacon) {
        sendBeacon(url, params)
    } else {
        sendImage(url, params)
    }
}

Related Documents

Deep dive into front‑end monitoring principles

Front‑end event tracking collection and reporting schemes

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.

Performance Monitoringevent trackingError HandlingData Reporting
ELab Team
Written by

ELab Team

Sharing fresh technical insights

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.