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.

ScenarioSlow FramesFrozen Frames
15 all 500ms0
210 all 20ms0
301 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.

ScenarioCalculationFrames Delay
1(500ms - 16.67ms) * 52416.65ms
2(20ms - 16.67 ms) * 1033.3ms
3800ms - 16.67ms783.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 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.

Copied
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
You can edit this page on GitHub.