Inspect JS traces from Vega Apps

Tracing is an effective way to narrow down points of interest when optimizing your app code.

Vega has built-in support for Perfetto which is a popular developer tool to record, analyze and visualize traces from App’s code.

This article provides step-by-step instructions for,

  1. Adding traces in an App’s JS code
  2. Record App traces
  3. Analyze App Traces in Perfetto UI

Add Traces in App code

Systrace is a React Native API to emit traces from App JS code and is supported in React Native for Vega.

Follow the below steps, to add traces in your App’s JS code using the Systrace API.

Step 1: Identify the section of the code to trace

First, identify the section of the code you want to measure using tracing.

It is a good practice to add traces around the hottest parts of your code i.e. the ones that are executed most often or take the longest.

You can also work backwards from the performance issue you are investigating, and add traces around the code is executed during the issue.

For example, if you are investigating a slow focus issue that surfaces when scrolling in a FlatList component that renders a TouchableOpacity component, you can add traces around the callback function passed to onFocus prop of the TouchableOpacity component

Step 2: Add traces around the functions of interest

After you have identified the functions of interest, add traces around that function. Provide a unique and meaningful name in the traces that you can easily find later during analysis.

For example, for an onFocus issue in TouchableOpactity the tracing code would look something like this,

//Example Systrace code in KeplerVideoApp
import { Systrace } from "react-native";
const FocusableElement = ({
  focusableElementRef,
  children,
  onPress,
  onBlur,
  onFocus,
  getFocusState,
  onFocusOverrideStyle,
  style,
  hasTVPreferredFocus,
  ...otherProps
}: FocusableElementProps) => {
  const [isFocused, setIsFocused] = useState(false);
  const focusHandler = () => {
    Systrace.beginEvent("KeplerVideoApp:FocusedElement:onFocus"); // ---> Begin Trace
    setIsFocused(true);
    getFocusState?.(true);
    onFocus?.();
    Systrace.endEvent(); // ---> End Trace
  };
  const blurHandler = () => {
    setIsFocused(false);
    getFocusState?.(false);
    onBlur?.();
  };

  return (
    <TouchableOpacity
      ref={focusableElementRef}
      activeOpacity={1}
      hasTVPreferredFocus={hasTVPreferredFocus}
      onFocus={focusHandler}
      onBlur={blurHandler}
      onPress={onPress}
      style={[style, isFocused ? onFocusOverrideStyle : undefined]}
      testID={otherProps.testID}
      {...otherProps}
    >
      {children}
    </TouchableOpacity>
  );
};

Record App Traces

After you have added the necessary traces in the App JS code, rebuild your App, run it on a Vega device, and record the traces.

Step 1: Rebuild Your App

Rebuild your App to ensure that the added traces are included in the App bundle.

A ‘Release’ build is recommended to accurately measure the trace durations.

Refer to Build Your App for steps.

Step 2: Install and Run your App

Install and the run the version of the app built in the previous step to ensure the traces you added in the code are recorded.

It is recommended to run the app on a Vega device to accurately measure the trace durations.

Refer to Run Your App for steps.

Step 3: Record App Traces

To record the traces, do a recording of the scenario that has a performance issue, using the ‘Activity Monitor’ Tool in Vega Studio IDE or CLI

For example, for a scrolling issue in onFocus handler within TouchableOpactity that is part of a FlatList, the recording steps would look something like this

  1. Launch the App
  2. Run Activity Monitor
  3. Start Recording
  4. Perform Scrolling within the App
  5. Stop Recording

Once recording is complete, you should see the output files recorded by Activity Monitor in your project under generated directory.

Activity Monitor creates one directory under generated per recording session. The name of the directory indicates the recording timestamp.

The generated directory for Activity Monitor contains the following files

FileName Description
iter*_trace*_-converted.json JS CPU Profiler trace file transformed for Vega Studio IDE
iter*_trace*_-original.json JS CPU Profiler trace file compatible with Chrome Dev Tools
iter*_vs_trace Perfetto Trace File
*trace-recorder.json Trace file recorded by Activity Monitor
You can open this file using Recording View to inspect data collected by Activity Monitor

Analyze App Traces in Perfetto UI

Step 1: Open trace file in Perfetto UI

After you have collected the traces, you can inspect them in Perfetto UI to analyze further and understand if the time taken between the trace points is expected.

Navigate to https://ui.perfetto.dev/ to access Perfetto UI, then click on “Open trace file” in the left menu and select the iter*_vs_trace file from the generated directory.

Alternately, you can also drag the iter*_vs_trace file from the generated directory directly on the https://ui.perfetto.dev/ webpage.

Step 2: Analyze App traces

After the trace file loads in Perfetto, you can find the traces you added in the code using the search bar at the top, by entering the trace name.

For example, a KeplerVideoApp:FocusedElement:onFocus trace added in the onFocus handler appears like this,

Once you locate the trace, analyze duration of the trace across all occurrences and check if its expected. If there traces stacked below a trace, see if the stack trace is expected.