Skip to content

PATTERN Cited by 1 source

Bundle-size budget for browser telemetry

Problem

Observability in a browser context has a cost server-side observability never has: every byte of the telemetry SDK adds to page weight and competes with customer-facing JavaScript for the critical render path. Default OpenTelemetry JS browser distributions bundle more auto-instrumentation + exporters + SDK machinery than any given site actually uses; off-the-shelf installation can easily add hundreds of kilobytes to the initial page payload.

Three knock-on effects:

  1. Page weight → slower first contentful paint, worse Core Web Vitals (LCP, FCP).
  2. More JavaScript → longer parse/compile/execute on low-end devices → worse INP.
  3. Observability tooling itself regresses the metric it's trying to measure (page performance) — a self-defeating shape.

Solution

Treat browser-side observability as a byte-budget engineering problem, not a plug-and-play install:

1. Cherry-pick upstream packages

Don't install @opentelemetry/sdk-node-auto-instrumentations- style meta packages. Install only the specific tracer, specific exporter, and specific auto-instrumentations you actually need — see concepts/cherry-picked-instrumentation-payload.

2. Split critical vs lazy payload

Packages that must be on the critical page-load path (e.g. tracing page load itself, generating propagation context for API requests) go in the initial bundle; everything else is loaded asynchronously after the critical render path completes.

3. Low-priority transport

Use navigator.sendBeacon() (concepts/send-beacon-telemetry-transport) instead of fetch() / XMLHttpRequest for telemetry export so network requests sit at the lowest priority tier below all customer-facing requests.

4. Baseline + budget

Set an explicit bundle-size budget for the telemetry payload and check it in CI. If a new OTel dependency exceeds the budget, it gets broken into critical + lazy halves before merging.

Zalando numbers

Source: sources/2024-07-28-zalando-opentelemetry-for-javascript-observability-at-zalando:

  • First off-the-shelf telemetry package trialled: ~400 KB added to page size — "we tried to integrate some telemetry packages only to realise they added about 400 KBs to the page size!"
  • Final cherry-picked Zalando SDK: ~30 KB added. >13× reduction.
  • Non-critical packages deferred to after critical load path.
  • Network transport via sendBeacon() at lowest priority.

When to use this pattern

  • Customer-facing web application where page-load performance matters (e-commerce checkout flow, news, SaaS login).
  • OTel JS browser integration where you'd otherwise take the default @opentelemetry/sdk-trace-web + auto-instrumentation bundle.
  • Fleet of web apps — define the budget once, enforce fleet-wide via the platform team's SDK (patterns/observability-sdk-as-zalando-specific-wrapper).

When not to use this pattern

  • Internal-only tools with captive audiences and no page-load performance budget — don't over-engineer a 300 KB dashboard.
  • Native mobile or Electron apps — no browser critical-render- path constraint (though code-size matters for install-size reasons).

Failure modes

  • Budget without enforcement — written-down targets that no CI check validates drift upward over releases.
  • Lazy load breaks page-load tracing — if the tracer for the initial navigation span is deferred it misses the very thing it's supposed to instrument. Page-load tracer must stay in the critical bundle.
  • SendBeacon loses data on aggressive unload — low priority means the browser may cancel queued beacons at unload; real-world data loss rate is small but nonzero. Don't use sendBeacon for audit-grade data.
  • Over-trimming breaks auto-instrumentation surface — cherry-picking too aggressively can leave holes where key framework events aren't instrumented. The SDK team has to own the completeness audit.

Sibling patterns

Alternative evaluated

Grafana Faro — Zalando called this out as "a great package to check out if you are starting from scratch". Faro is a browser-SDK purpose-built for frontend observability with bundle-size consciousness as a design primitive, so if you're greenfield and don't already have an OTel-based SDK family, Faro may sidestep the cherry-picking work.

Seen in

Last updated · 550 distilled / 1,221 read