perf(session-replay): Reduce capture stutters#7851
Conversation
Defer screenshots during active interactions and dense animations so replay capture avoids the hottest UI frames. Back off the screenshot cadence when capture is slow, then recover toward the configured frame rate after faster captures.
|
Drive replay captures from a default-mode run loop observer so screenshot work runs after UI work instead of from the display link.
| activities, | ||
| true, | ||
| CFIndex.max, | ||
| { _, activity, context in |
There was a problem hiding this comment.
The first parameter in this callback should be the observer, you can access the mode property and check if it's .interactive. That's how you can avoid firing the capture logic if the user is scrolling
Observe replay capture scheduling in common modes and read the current run loop mode from the observer callback. Skip capture bookkeeping while the run loop is in tracking mode so scrolling does not trigger screenshots.
Use the block-based run loop observer callback and keep replay capture timing state named around screenshot timestamps. Flatten the deferral and adaptive interval branches without changing capture thresholds.
Keep tracking-mode suppression in the run loop scheduler and leave the capture guard focused on active interactions and animations.
|
I quickly glanced over the changes and while I believe it to be viable (with the adoption of the existing My main concern is that we are not taking screenshots at a one second interval anymore, but instead the interval can be longer than that (less than a second is debounced). In that case we need to look into two topics:
|
Reduce session replay capture stutters by avoiding screenshots on the hottest UI frames and backing off when capture itself is slow.
The screenshot path is unchanged, so fidelity stays the same: this still uses the existing screenshot provider, masking, scale, and image pipeline. The change only adjusts when we ask for a screenshot. Captures are briefly deferred while the run loop is tracking, a scroll view/control/gesture is actively interacting, or the layer tree has enough active animations to indicate visible motion. Deferral is bounded to one second, so replay still produces frames during long interactions.
Slow synchronous captures now also feed an adaptive interval. If a capture takes at least 50ms, the next interval backs off up to five seconds, then recovers toward the configured frame rate after faster captures.
Benchmark comparison from the attached run on the iOS 26.4 simulator:
Validated with the reproducible sample provided by a customer: 1st row is after, 2nd row is before
Replay Before: https://sentry-sdks.sentry.io/explore/replays/78440eab9df54aa1abfc2a670354b488
Replay After: https://sentry-sdks.sentry.io/explore/replays/277fbeaf481044a4a4d9017f54c85e00/
#skip-changelog
Closes #6885