This repository has been archived by the owner on Aug 14, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 225
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add docs for the performance metric frames delay.
- Loading branch information
1 parent
930640a
commit 58f8ded
Showing
3 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
--- | ||
title: "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. | ||
|
||
## Background | ||
|
||
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. | ||
|
||
## Specification | ||
|
||
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 <Link to="/sdk/performance/span-data-conventions/#mobile">span data</Link> | ||
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](https://cucumber.io/docs/gherkin/reference/). | ||
|
||
|
||
```Gherkin | ||
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters