Context
In #5907, we added frames.delay span data by creating RNSentryFrameDelayCollector — a listener-based collector that registers with sentry-java's SentryFrameMetricsCollector to accumulate per-frame delay data. This works, but it duplicates work already done internally by sentry-java's SpanFrameMetricsCollector, adding unnecessary overhead:
- Double listener callbacks: Every frame triggers two listener callbacks on the UI thread (one for sentry-java's internal collector, one for ours)
- Double storage: Two separate data structures holding the same per-frame delay records
- Redundant computation: Both collectors compute delay overlap with time ranges independently
Proposed Solution
Add a queryable API to sentry-java (on SentryFrameMetricsCollector or a new utility), mirroring iOS's existing SentryFramesTracker.getFramesDelaySPI:
// New method on SentryFrameMetricsCollector (or SentryAndroidOptions accessor)
public SentryFramesDelayResult getFramesDelay(long startSystemNanos, long endSystemNanos);
public class SentryFramesDelayResult {
public final double delayDuration; // in seconds, -1 if incalculable
public final int framesContributingToDelayCount;
}
iOS Reference
sentry-cocoa already exposes this via SentryFramesTracker.getFramesDelaySPI(_:endSystemTimestamp:) which returns SentryFramesDelayResultSPI with delayDuration and framesContributingToDelayCount. The RN SDK calls this directly without any custom collector.
Implementation Plan
Step 1: sentry-java changes
-
Add getFramesDelay(startNanos, endNanos) to SentryFrameMetricsCollector (or expose it on SpanFrameMetricsCollector)
- Internally,
SpanFrameMetricsCollector already stores frame records and computes delay via captureFrameMetrics() — extract the delay calculation into a standalone query method
- Accept
System.nanoTime()-based timestamps
- Handle partial frame overlap at query boundaries (same logic already exists in
SpanFrameMetricsCollector.captureFrameMetrics())
- Return delay in seconds or -1 if incalculable
-
Add SentryFramesDelayResult data class
-
Expose through SentryAndroidOptions.getFrameMetricsCollector() (already exists)
Step 2: sentry-react-native changes
- Delete
RNSentryFrameDelayCollector.java entirely
- Simplify
RNSentryModuleImpl.fetchNativeFramesDelay():
public void fetchNativeFramesDelay(double startTimestampSeconds, double endTimestampSeconds, Promise promise) {
SentryOptions options = Sentry.getCurrentScopes().getOptions();
if (!(options instanceof SentryAndroidOptions)) {
promise.resolve(null);
return;
}
SentryFrameMetricsCollector collector = ((SentryAndroidOptions) options).getFrameMetricsCollector();
// ... timestamp conversion ...
SentryFramesDelayResult result = collector.getFramesDelay(startNanos, endNanos);
promise.resolve(result != null && result.delayDuration >= 0 ? result.delayDuration : null);
}
- Remove listener start/stop from
enableNativeFramesTracking() / disableNativeFramesTracking()
Benefits
- Zero additional per-frame overhead (no duplicate listener)
- No duplicate data storage
- Simpler RN SDK code (delete ~130 lines, replace with ~5 lines)
- Consistent API shape across iOS and Android
Blocked on
- sentry-java exposing a queryable frames delay API (needs a sentry-java issue/PR)
Context
In #5907, we added
frames.delayspan data by creatingRNSentryFrameDelayCollector— a listener-based collector that registers with sentry-java'sSentryFrameMetricsCollectorto accumulate per-frame delay data. This works, but it duplicates work already done internally by sentry-java'sSpanFrameMetricsCollector, adding unnecessary overhead:Proposed Solution
Add a queryable API to sentry-java (on
SentryFrameMetricsCollectoror a new utility), mirroring iOS's existingSentryFramesTracker.getFramesDelaySPI:iOS Reference
sentry-cocoa already exposes this via
SentryFramesTracker.getFramesDelaySPI(_:endSystemTimestamp:)which returnsSentryFramesDelayResultSPIwithdelayDurationandframesContributingToDelayCount. The RN SDK calls this directly without any custom collector.Implementation Plan
Step 1: sentry-java changes
Add
getFramesDelay(startNanos, endNanos)toSentryFrameMetricsCollector(or expose it onSpanFrameMetricsCollector)SpanFrameMetricsCollectoralready stores frame records and computes delay viacaptureFrameMetrics()— extract the delay calculation into a standalone query methodSystem.nanoTime()-based timestampsSpanFrameMetricsCollector.captureFrameMetrics())Add
SentryFramesDelayResultdata classExpose through
SentryAndroidOptions.getFrameMetricsCollector()(already exists)Step 2: sentry-react-native changes
RNSentryFrameDelayCollector.javaentirelyRNSentryModuleImpl.fetchNativeFramesDelay():enableNativeFramesTracking()/disableNativeFramesTracking()Benefits
Blocked on