Skip to content

Sentry Frontend Profiling: How to Interpret Results

This project enables frontend performance tracing + UI profiling via the Sentry browser SDK loaded from the public-key loader (js.sentry-cdn.com/...). This doc explains how to read and act on the data in Sentry.

How profiling is wired in this codebase

  • Template initialization: we keep the public-key loader script and call Sentry.init(...) once it finishes loading (via Sentry.onLoad(...)).
  • website/templates/base.html
  • website/templates/base_v2.html
  • website/templates/base_new.html
  • website/templates/admin_dashboard.html
  • Environment + sampling: values are provided by the Django context processor:
  • website/context_processors.pysentry_frontend_config
  • Registered in skyportal/settings.py under TEMPLATES[0]["OPTIONS"]["context_processors"]

Important notes: - We do not inject a DSN string into templates. The Sentry loader already contains the DSN internally; we rely on the loader and only configure environment + sampling + integrations. - Trace propagation is configured to target localhost, skyportal.ai, and URLs matching ^/api/.

What data you should expect to see

  • Transactions (Performance): High-level timing spans for page loads (and navigation/history events if applicable) plus (sometimes) XHR/fetch spans.
  • Profiles (Profiling): CPU-time samples showing which JavaScript functions were running and how much time was spent in them. This is what helps debug “UI feels slow/janky”.

The most useful workflow is: start from a slow transaction → open its profile → find the hottest functions → map them back to code.

Where to look in Sentry

  • Performance → Transactions: find slow page loads (and navigations, if applicable).
  • Profiling → Profiles (or the profiling panel on a transaction): inspect CPU hotspots.
  • Trace view: correlate frontend work with backend spans where applicable.

Reading a profile (practical guide)

Profiles are sampled. You won’t always get one, and a single profile isn’t “the truth”—use multiple samples.

Key panels/concepts

  • Flamegraph:
  • Wider blocks = more time spent in that function (or its children).
  • Top frames are usually entry points (event handlers, render loops, timers).
  • Look for large, repeated stacks and expensive leaf functions.

  • Call tree / “Top functions”:

  • Use this to quickly identify the heaviest functions across the sample.
  • Drill down to see which callers drive the cost.

What “bad” looks like

  • Long main-thread work: big continuous stacks indicating the UI thread is blocked.
  • Repeated expensive callbacks: scroll/resize handlers doing heavy work.
  • Tight loops / heavy JSON parsing: large time in parsing, serialization, array operations.
  • Layout thrash: patterns where code repeatedly reads and writes layout (often seen as DOM/layout-related stacks).

What to do with a hotspot

Once you find an expensive function: - Identify the call site (who calls it and how often). - Decide whether to: - Reduce frequency (debounce/throttle, fewer renders, fewer listeners) - Reduce work per call (memoization, caching, move work off main thread) - Avoid unnecessary DOM/layout work

Correlating frontend and backend performance

When a transaction is slow, first decide whether it’s: - Network-bound (backend/API slow): slow spans for requests. - CPU-bound (frontend JS slow): profile shows heavy main-thread work. - Both: slow API and expensive client-side rendering/processing.

Useful heuristics: - If TTFB/network spans dominate: focus on backend, payload size, caching. - If profile hotspots dominate: focus on rendering logic, client transforms, event handlers.

Sampling rates and expectations

Sampling is environment-specific (set server-side and rendered into templates): - production: traces 0.1, profiles 0.1 - staging: traces 0.3, profiles 0.2 - development: traces 1.0, profiles 0.5 - test/other: disabled

Implications: - In prod, you may need to reproduce multiple times to capture a profile. - In dev/staging, you should see profiles more often.

Common pitfalls

  • One-off spikes: A single slow profile can be noise—look for patterns.
  • Minified stacks: If stacks aren’t readable, ensure release/versioning + sourcemaps are set up (outside the scope of this doc).
  • Ad blockers: Can block Sentry scripts; missing data might be caused by blockers.
  • Background tabs / throttling: Browser throttling affects performance measurements.

Quick checklist when investigating “UI is slow”

  1. Find a slow transaction in Performance.
  2. Open the profile associated with it.
  3. Identify top hotspots (flamegraph/call tree).
  4. Determine if it’s:
  5. Too much work per call
  6. Too many calls
  7. Network-bound / waiting on backend
  8. Make one targeted change and re-measure.