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,
- Adding traces in an App’s JS code
- Record App traces
- 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
- Instructions for recording in Vega Studio IDE
- Instructions for recording from CLI
- Run the
perf record --app-name <<interactive-component-id>>
command to record a trace - Run the
perf activity-monitor --app-name <<interactive-component-id>>
if therecord
command fails to work.
- Run the
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
- Launch the App
- Run Activity Monitor
- Start Recording
- Perform Scrolling within the App
- 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.