Course contentsShow
← Node.js
Lesson 1763 of 1,98015. Logging, Observability, and MetricsFree lesson

Telemetry for Client-Side Applications

Extend observability to the browser to track user-perceived performance and errors.

Telemetry for Client-Side Applications

In this lesson, you will learn how to extend your existing backend observability strategy into the browser to capture real-user performance data and client-side exceptions.

While your backend telemetry gives you a view of server health, the "last mile" of your application lives in the user’s browser. Factors like network speed, device processing power, and complex client-side state transitions can create performance bottlenecks that are invisible from the server logs. To bridge this gap, you need to instrument the frontend to send telemetry back to your observability pipeline.

Measuring Perceived Performance

User-perceived performance is best captured using the Web Vitals initiative (like Largest Contentful Paint or First Input Delay). Since these metrics occur entirely within the browser, you must hook into the PerformanceObserver API to collect these measurements as they happen.

// Capture Largest Contentful Paint (LCP)
new PerformanceObserver((entryList) => {
  const entries = entryList.getEntries();
  const lastEntry = entries[entries.length - 1];
  
  // Send to your telemetry endpoint
  navigator.sendBeacon('/log/performance', JSON.stringify({
    metric: 'LCP',
    value: lastEntry.startTime,
    url: window.location.href
  }));
}).observe({ type: 'largest-contentful-paint', buffered: true });

Capturing Client-Side Errors

Similarly, errors in the browser—such as unhandled promise rejections or script syntax errors—often go unnoticed because they happen on the user's machine. You can wrap your global error handling to report these back to your unified observability system:

window.addEventListener('error', (event) => {
  fetch('/log/errors', {
    method: 'POST',
    body: JSON.stringify({
      message: event.message,
      stack: event.error?.stack,
      timestamp: Date.now()
    }),
    keepalive: true // Ensure the request finishes even if the page unloads
  });
});

Strategic Integration

When implementing this, remember the importance of minimizing instrument overhead. Browsers are resource-constrained; excessive telemetry collection can degrade the very user experience you are trying to measure. Use navigator.sendBeacon or the keepalive flag on fetch requests to ensure logs are sent asynchronously without blocking the main thread or preventing page navigation. By centralizing this frontend data alongside your server-side traces, you gain a holistic view of the entire request lifecycle.

Key Takeaway: Effective client-side telemetry bridges the visibility gap between backend performance and the actual user experience by reporting browser-native metrics and errors directly to your observability platform.