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 (viaSentry.onLoad(...)). website/templates/base.htmlwebsite/templates/base_v2.htmlwebsite/templates/base_new.htmlwebsite/templates/admin_dashboard.html- Environment + sampling: values are provided by the Django context processor:
website/context_processors.py→sentry_frontend_config- Registered in
skyportal/settings.pyunderTEMPLATES[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”
- Find a slow transaction in Performance.
- Open the profile associated with it.
- Identify top hotspots (flamegraph/call tree).
- Determine if it’s:
- Too much work per call
- Too many calls
- Network-bound / waiting on backend
- Make one targeted change and re-measure.