Vega App Performance Series, Part 1: Understanding Fluidity and Responsiveness Metrics

Introduction

Users expect apps to be smooth and responsive. When they click a button on a remote, the UI should respond instantly. When they scroll through content, it should glide without stuttering. When they hit play, video should start instantly. Sluggish navigation, stuttering scrolls, or delayed video playback create friction that drive users away. This isn’t just about raw performance metrics: it’s about how the app feels.

In this series, we focus on two qualities that are critical factors to make a great app: fluidity and responsiveness.

  • Responsiveness means the app reacts immediately when users interact with it. There’s little-to-no perceptible delay between pressing a D-pad button and seeing the UI update.
  • Fluidity (also referred to as “smoothness”) means animations, scrolling, and video playback are smooth and consistent, free from stutters, jank, or dropped frames.

Building performant apps follows three steps: measure, investigate, and optimize. This three-part series walks through that process for fluidity and responsiveness in your VegaScript (React Native) apps using Vega Studio.

  • Part 1 (this article): Covers the key metrics and how to measure them using the KPI Visualizer. This establishes the baseline understanding you’ll need for the rest of the series.
  • Part 2: Investigating Performance Issues walks through a real example of identifying performance problems. We’ll examine a degraded implementation, measure its impact with the KPI Visualizer, and use Perfetto traces to diagnose root causes.
  • Part 3: Optimizing for Fluidity and Responsiveness covers fixes and optimization techniques. We’ll apply targeted solutions to the problems identified in Part 2 and share best practices for keeping your app performant.

Understanding the Key Metrics

Before diving into tooling and examples, let’s understand what we’re measuring. Vega Dev Tooling provides several KPIs (Key Performance Indicators) that directly correlate with user-perceived fluidity and responsiveness.

Fluidity (Smoothness) KPIs

These metrics measure how smooth (or “fluid”) your app’s animations, scrolling, and video playback appear.

Metric What It Measures Guideline
UI Fluidity % The percentage of frames successfully rendered during on-screen UI interactions. Represents overall smoothness during scrolling, navigation, and animations. > 99%
3+ Consecutive Dropped Frames (UI) The number of instances where your app drops 3 or more consecutive frames during UI interactions like scrolling and navigation. Causes noticeable stuttering. Minimize
5+ Consecutive Dropped Frames (UI) The number of instances where your app drops 5 or more consecutive frames during UI interactions. Causes significant disruption to the user experience. 0
Video Fluidity % The percentage of time video plays at its intended frame rate. Dropped frames during playback create visible artifacts and stuttering. > 99%
3+ Consecutive Dropped Frames (Video) Instances of 3 or more frames dropped in sequence during video playback. Causes noticeable playback stuttering. Minimize
5+ Consecutive Dropped Frames (Video) Instances of 5 or more frames dropped in sequence during video playback. Causes significant playback disruption. Minimize

Responsiveness KPIs

These metrics measure how quickly your app reacts to user input.

Metric What It Measures Guideline
App Event Response Time - Focus The scheduling latency between when a native UI event occurs (like a D-pad press) and when your JavaScript code processes it. Tracks the delay for focus events (onFocus/onBlur) between the native UI thread and the JavaScript thread. < 200ms
Key Pressed Latency The time from a key press input event on the UI thread to its corresponding JavaScript callback invocation. Captured during video playback scenarios. < 100ms
Key Released Latency The time from a key release input event on the UI thread to its corresponding JavaScript callback invocation. Captured during video playback scenarios. < 100ms
5+ Consecutive Delayed Events The number of instances where 5 or more consecutive focus events experience significant delay in processing. Indicates “laggy” navigation where the focus indicator trails behind button presses. 0
Time to First Video Frame (TTFVF) The complete end-to-end time from when a user presses “Play” to when the first video frame renders on screen. Includes input event processing, network requests, video buffering, media player initialization, and first frame rendering. < 2.5s
Time to First Frame (TTFF) Cool Start Measures the time from app launch to first frame render. The OS calculates TTFF without requiring app code markers. < 1.5s
Time to Fully Drawn (TTFD) Cool Start Measures the time from app launch to when the app is ready for user interaction. Requires implementing a fully drawn marker in your app to signal when essential components have loaded. < 8.0s
Time to Player Start The time from when a user presses “Play” to when the media player instance is created. < 2500ms
Player Start to First Video Frame The time from when a user presses “Play” to when the first video frame is rendered on screen. < 2500ms

Getting Started with Vega Developer Tools

Vega Studio (the VS Code extension for Vega development) includes the Vega App KPI Visualizer: a comprehensive tool that automates performance measurement across multiple test iterations and generates detailed reports.

Prerequisites

Before measuring KPIs, ensure you have:

  1. Vega Studio extension (version 0.22 or later) installed in VS Code
  2. Vega Performance API installed in your app:
    npm install @amazon-devices/kepler-performance-api
    
  3. Fully drawn markers implemented in your app (required for accurate TTFD measurement)
  4. A connected Fire TV Stick 4K Select device

For UI and video fluidity tests, you’ll also need to set up Appium for automated UI interactions.

For complete setup instructions, see Measure App KPIs.

Running the KPI Visualizer

The KPI Visualizer can be launched from VS Code or the command line:

From VS Code:

  1. Open the command palette (Cmd+Shift+P on Mac, Ctrl+Shift+P on Linux)
  2. Enter Vega: Launch App KPI Visualizer
  3. Select your test scenario (cool start, warm start, UI fluidity, video fluidity, etc.)

From CLI:

# Check environment readiness
vega exec perf doctor --app-name com.example.myapp.main

# Run KPI visualizer for app launch metrics
vega exec perf kpi-visualizer --app-name com.example.myapp.main --kpi cool-start-latency

# Run KPI visualizer for UI fluidity (requires test scenario)
vega exec perf kpi-visualizer --app-name com.example.myapp.main --kpi ui-fluidity --test-scenario ui_fluidity_test.py

The tool runs multiple iterations (3 by default) and generates a report with statistical analysis.

For detailed instructions on running tests and interpreting results, see Measure App KPIs and Measure Fluidity and Foreground Memory.

Perfetto Integration

One of the most powerful features of the Vega tooling is automatic Perfetto trace generation. Every KPI test run produces Perfetto-compatible trace files that provide microsecond-level visibility into your app’s behavior.

These traces capture:

  • CPU, GPU, and memory activity at the system level
  • JavaScript execution, rendering, and network calls
  • Frame timing data for identifying exactly when and why frames dropped
  • Thread activity showing scheduling and blocking

Adding Custom Traces to Your App

While Vega automatically captures system-level traces, adding custom trace points to your code enables much deeper debugging. Without custom traces, you’ll see that something is slow, but not which specific function is causing the problem.

Use React Native’s Systrace API to instrument key areas of your code:

import {Systrace} from 'react-native';

const FocusableElement = ({onFocus, children, ...props}) => {
  const [isFocused, setIsFocused] = useState(false);

  const focusHandler = () => {
    Systrace.beginEvent('MyApp:FocusableElement:onFocus');
    
    setIsFocused(true);
    onFocus?.();
    
    Systrace.endEvent();
  };

  return (
    <Pressable onFocus={focusHandler} {...props}>
      {children}
    </Pressable>
  );
};

Where to add traces:

  • Focus and blur handlers (for navigation performance)
  • Data fetching and processing functions
  • Render methods of complex components
  • Any code you suspect might be slow

Important: Every Systrace.beginEvent() must have a corresponding Systrace.endEvent(). If traces appear incomplete in Perfetto, check that early returns or exceptions don’t prevent endEvent() from executing.

After adding traces, rebuild your app with a Release configuration and run your KPI tests. Your custom traces will appear in Perfetto alongside system traces, making it easy to correlate your code execution with frame timing.

For detailed guidance on recording and analyzing traces, see Inspect Traces.

Locating Trace Files

After running a KPI test, trace files are saved in your project’s output/ directory:

output/kpi-visualizer-result-[timestamp]/
├── aggregated-kpi-report.json
└── [test-name]/
    ├── iter_1_vs_trace    # Perfetto trace file
    ├── iter_1_vs_trace.log
    └── ...

You can open these traces directly in Vega Studio by clicking on a trace file or in Perfetto UI.

We’ll explore how to use Perfetto for debugging in Part 2.

What’s Next

Now that you understand the key metrics and how to measure them, head over to Part 2: Investigating Performance Issues where we’ll:

  • Walk through real examples of UI fluidity and responsiveness issues
  • Measure the impact of common anti-patterns using the KPI Visualizer
  • Use Perfetto traces to diagnose root causes
  • Analyze JavaScript thread behavior to identify bottlenecks

Additional Resources

Performance Measurement

https://developer.amazon.com/docs/vega/latest/fluidity-foreground.html

Optimization Guidance


Last updated: December 2025