Frames Delay
Frames Delay is the user-perceived delayed duration of rendered frames. SDKs can attach this information to spans. We recommend implementing this feature for mobile and desktop SDKs.
This section explains why frames delay is a better metric than slow and frozen frames. If you already know why, you can skip this section.
On Mobile, slow and frozen frames are well-established metrics for tracking the responsiveness of applications. A phone or tablet typically renders 60 frames per second (fps). At 60 fps, every frame has 16 or 16.67 ms to render:
- Slow Frames: Using 60 fps, slow frames are frames that take more than 16.67 ms to render.
- Frozen Frames: Frozen frames are frames that take longer than 700 ms to render.
The major downside is that they lack essential information on how long they lasted, which is a significant problem when prioritizing which unresponsive application parts need improvement. The following scenarios highlight the problem when prioritizing by looking at slow and frozen frames.
Scenario | Slow Frames | Frozen Frames |
---|---|---|
1 | 5 all 500ms | 0 |
2 | 10 all 20ms | 0 |
3 | 0 | 1 with 800ms |
When comparing the different scenarios, a user might want to fix scenario 3 first because it contains one frozen frame. When comparing scenarios 1 and 2, they would pick scenario 2 cause it has more slow frames. While scenario 2 looks worse, the user experience is way worse for scenario 1 because the slow frames last longer.
That's where a new metric called frames delay comes to the rescue. Frames delay represents the delayed frame render duration of all frames. The frame delay for one frame is actual frame duration - expected frame duration
. For example, with 60 fps the expected frame duration is 16.67 ms. When a frame takes 20 ms to render, the frame delay is 20ms - 16.67ms = 3.33ms
.
Let's calculate the frames delay for scenarios 1 - 3.
Scenario | Calculation | Frames Delay |
---|---|---|
1 | (500ms - 16.67ms) * 5 | 2416.65ms |
2 | (20ms - 16.67 ms) * 10 | 33.3ms |
3 | 800ms - 16.67ms | 783.33ms |
Now, when prioritizing the user-perceived degraded responsiveness by frames delay, we get 1, 3, 2 instead of 3, 2, 1 when looking at slow and frozen frames.
Frames delay represents the delayed frame render duration of all frames. The frame delay for one frame is actual frame duration - expected frame duration
. For example, with 60 fps the expected frame duration is 16.67 ms. When a frame takes 20 ms to render, the frame delay is 20ms - 16.67ms = 3.33ms
. As the expected frame rate can change at any time, SDKs must check the expected frame rate for every frame. The frame delay for a span is the sum of frame delays for all slow and frozen frames during the start and end time of the span.
SDKs should attach frames delay in seconds to spans via span data and attach frames delay to all spans, regardless of on which thread a span runs, and as well to concurrently running spans. For transactions SDKs should send frames delay via the root span with span data. While it makes sense to calculate frames delay in milliseconds, SDKs must send frames delay in seconds, as SDKs already use seconds for most timestamps. For the specification here, we use milliseconds cause they are easier to read.
The specification is written in the Gherkin syntax.
Scenario: Slow and frozen frames
Given a frame rate of 60 fps
And 2 frames with 300 ms
And 1 frame with 900 ms
And 10 frames with 16.76 ms
When calculating the frames delay
Then the frames delay is (300 - 16.67) * 2 + 900 - 16.67 = 1449.99 ms
Scenario: Frame rate changes
Given 1 frame with 200 ms with 60 fps
And 2 frame with 500 ms with 120 fps
And 10 frames with 8.33 ms with 120 fps
When calculating the frames delay
Then the frames delay is 200 - 16.67 + (500 - 8.33) * 2 = 1166.67 ms
Scenario: Ongoing delayed frame
"""
[nf][ ------- ?? ------ ] | nf = normal frame, ?? = No frame information
[---- span duration ----]
When there is an ongoing delayed frame, the logic doesn't know how long it
will last and, therefore, has no frame information.
"""
Given a frame rate of 60 fps
And 1 frame with 16.67 ms
And 200 ms pass after without any frame being drawn
And no recorded delayed frame
When calculating the frames delay
Then the frames delay 200 ms - 16.67 ms = 183.33 ms
Scenario: Delayed frame starts before span
"""
[---- delayed frame ---- ]
[- span duration -]
"""
Given a frame rate of 60 fps
And a recorded delayed frame with a duration of 300 ms
When calculating the frames delay for the span 100 ms to 300 ms
Then the frames delay is the full duration of the span of 200ms
Scenario: Delayed frame starts shortly before span
"""
[| e | delayed frame ---- ] e = the expected frame duration
[--- span duration --- ]
"""
Given a frame rate of 60 fps
And a recorded delayed frame with a duration of 300 ms
And the delayed frame started at 0 ms shortly before the span
When calculating the frames delay for the span 10 ms to 300 ms
Then the frames delay is 300 ms - 16.67 ms = 283.33 ms, which is only the delayed part
of the delayed frame
And the expected frame duration part of the delayed frame is not added as a frame delay
Scenario: Delayed frame starts and ends before the span
"""
[| e | delayed frame ------ ] e = the expected frame duration
[--- span duration --- ]
"""
Given a frame rate of 60 fps
And a recorded delayed frame with a duration of 310 ms
And the delayed frame started at 0 ms shortly before the span
When calculating the frames delay for the span duration of 10 ms to 300 ms
Then the frames delay is 300 ms - 6.67 ms = 293.33 ms, which is only the delayed part of
the delayed frame having an intersection with the span duration
And the expected frame duration part of the delayed frame is not added as a frame delay
Scenario: One delayed frame starts shortly before the end of a span
"""
[| e | delayed frame ][| e | delayed frame - ] e = the expected frame duration
[---- span duration ---- ]
"""
Given a frame rate of 60 fps
And a recorded delayed frame with a duration of 290 ms
And a recorded delayed frame with a duration of 200 ms
When calculating the frames delay for the span duration of 0 ms to 300 ms
Then the frames delay is 290 ms - 16.67 ms = 273.33 ms
And the expected frame duration part of the second delayed frame is not added as a frame delay
Scenario: Two concurrent spans
"""
[| e | --- delayed frame--- ] e = the expected frame duration
[----- span 1 -----]
[---- span 2 ----]
"""
Given a frame rate of 60 fps
And a recorded delayed frame with a duration of 300 ms
When calculating the frames delay
Then the frames delay for span 1 is it's full duration of 180 ms
Then the frames delay for span 2 is it's full duration of 160 ms
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").