App Performance FAQ
Select the topic you want to learn more about:
- How to fix common TV app performance issues video
- App launch
- Slow scroll
- Key press latency
- App running out of memory
How to fix common TV app performance issues video
This video covers the following performance issues:
- Slow app launches
- Slow scrolling
- Keypress latency
- App memory issues
App launch
App launch and startup performance directly impacts user experience. Slow app launch frustrates users and leads to app abandonment. Code optimization during development speeds app launch times.
Common causes include:
- Large JavaScript (JS) bundle sizes.
- High network request latency during app startup.
Q: Why is app launch performance important?
A: App launch performance is important because it impacts user experience. Slow launches create poor first impressions and can lead to user abandonment. For details, see Measure Your App KPIs.
Q: What are the key metrics for measuring app launch performance?
A: The key metrics for measuring app launch performance are:
- Time-to-first-frame (TTFF).
-
Time-to-first-draw (TTFD).
For details, see App KPI metrics and guidelines.
Q: In what scenarios can my app launch?
A: App launches exist in the following scenarios:
- Cold start - App launches from scratch
-
Warm start - App resumes from background
For details, see Launch scenarios.
Q: What tools are available to measure launch performance?
A: Use the following tools to measure your app launch performance:
-
Vega App KPI Visualizer (preferred method).
For details, see Measure App KPIs.
-
Trace analysis using Perfetto.
For details, see Inspect Traces.
Q: How reliable is the TTFD measurement?
A: TTFD accuracy depends on correct placement of the fully_drawn marker
using the useReportFullyDrawn
hook. For details, see Fully drawn marker.
Q: What are the causes of slow app launches?
A: The main causes of slow app launches include:
- Network latency.
- Busy JS thread.
- Heavy UI components.
- Excessive re-renders.
- Unoptimized list configuration.
- Large JS bundle size.
- Inefficient image handling.
- Missing Native SplashScreen.
Q: How can I improve app launch performance?
A: You can improve app launch performance with the following solutions:
-
Implement Native SplashScreen API.
For details, see SplashScreen Manager.
-
Optimize image usage and size.
For details, see The image component.
-
Minimize unnecessary re-renders.
For details, see Avoiding re-renders and re-definitions.
-
Configure list components optimally.
For details, see How to handle large lists.
-
Reduce JS bundle size.
For details, see Reducing bundle size.
-
Use efficient image caching.
Q: How can I debug network-related launch issues?
A: You can debug network-related launch issues using Network Proxy to investigate calls, compare multiple test iterations, and analyze server response times and data volumes. For details, see Monitor Traffic with Network Proxy.
Q: How can I identify JS thread issues?
A: You can identify JS thread issues by using:
-
RN Systrace JS API for custom markers.
For details, see Inspect Traces.
-
Launch Mode CPU Profiler.
For details, see Run launch mode recording.
-
Thread State Visualizer.
For details, see Understand thread states.
-
why-did-you-render (wdyr) tool.
For details, see Investigate Component Re-rendering Issues.
Q: When the JavaScript thread is blocked for 8+ seconds, how can I diagnose this type of crash?
A: The system terminates apps when the JS thread remains blocked for 8+ seconds. You can resolve the issue by examining the aggregated crash report (ACR). Follow the instructions in Debug App Crash in Vega Studio.
The following entries confirm that a blocked JSThread caused the crash.
LCM_ANR_THREAD_NAME: JSThread
LCM_ANR_REASON: Thread Monitor
You can symbolicate the crash file using JavaScript mode to identify the JS execution state before the crash. If your code involves turbo module calls, symbolicate in native mode. Follow the instructions for native mode symblocation in Debug App Crash in Vega Studio.
Slow scroll
Slow or janky scrolling is a common UI performance issue that affects the smoothness of list navigation. Smooth scrolling should maintain a consistent frame rate without visual stutters or delays as users move through content.
Common causes include:
- Inefficient list rendering.
- Heavy computation on the JS thread.
- Complex layouts in list items.
- Large images or media content.
- Excessive re-renders during scroll.
Q: How to investigate slow scrolling issues?
A: Use the following tools to detect slow scrolling issues:
-
Vega App KPI Visualizer to measure and track UI fluidity % KPI.
For details, see Measure Fluidity and Foreground Memory.
-
JS CPU Profiling to identify hot functions and code taking more time in the JS Thread.
For details, see Monitor CPU Usage.
-
Flashlight tracks CPU utilization across all threads used by the app including: JS Thread, UI Thread and Render Thread.
For details, see Use Flashlight to Monitor Activity.
-
JS Thread State Visualization to track thread states of JS Thread, UI Thread and Render Thread of the app.
For details, see Understand thread states.
-
React DevTools profiler.
For details, see Use React DevTools to Inspect Component Rendering.
-
why-did-you-render (wdyr) tool.
For details, see Investigate Component Re-rendering Issues.
Q: How to mitigate slow scrolling issues?
A: Implement the following optimization strategies:
-
Avoid unnecessary re-renders.
For details, see Avoiding re-renders and re-definitions.
-
Optimize images.
For details, see The image component.
-
Reduce overdraw.
For details, see Detect Overdraw.
-
Follow animation best practices.
-
Implement debouncing for delayed execution. Debouncing executes function only after input stops.
- Search inputs: Process after typing ends
- Window resizing: Update after size stabilizes
-
Use throttling for consistent intervals. Throttling limits function calls to fixed intervals.
- Scroll handlers: Update position periodically
- Live updates: Refresh data at set intervals
- Real-time filters: Process input regularly
Example:
import debounce from "lodash/debounce";
import throttle from "lodash/throttle";
const SearchWithLodash = () => {
// Debounced search
const debouncedSearch = useCallback(
debounce((query) => {
fetchSearchResults(query);
}, 300),
[],
);
// Throttled scroll handler
const throttledScroll = useCallback(
throttle(() => {
// Handle scroll
}, 100),
[],
);
return (
<View>
<TextInput onChangeText={debouncedSearch} />
</View>
);
};
Key press latency
Key press latency measures the delay between a TV remote button press and the app's response. TV users expect instant feedback when navigating with remotes, making this metric important for user experience.
Common causes include:
-
Busy JavaScript Thread.
- Heavy computations (animations, synchronous operations) on the JS thread
- Unnecessary component re-rendering
- Inefficient event handling
-
Starved JS Thread.
- High CPU usage from other apps and process in the OS
- Background task interference
Q: How to investigate key press latency issues?
A: Use the following tools to detect key press latency issues:
-
JS Thread State Visualization to track thread states of JS Thread, UI Thread and Render Thread of the app.
For details, see Understand thread states.
-
JS CPU Profiling to identify performance bottlenecks.
For details, see Monitor CPU Usage.
-
React DevTools profiler.
For details, see Use React DevTools to Inspect Component Rendering.
-
why-did-you-render (wdyr) tool.
For details, see Investigate Component Re-rendering Issues.
Q: How to mitigate key press latency issues?
A: Implement the following optimization strategies:
- Use TVEventHandler.
-
Optimize focus management.
For details, see Optimizing your focus management UI.
-
Avoid unnecessary re-renders.
For details, see Avoiding re-renders and re-definitions.
-
Implement debouncing or throttling.
For details, see slow scroll.
App running out of memory
Vega platform optimizes memory to run apps and system services in parallel, ensuring a seamless user experience. The platform enforces strict memory limits:
- Foreground apps: 420Mb
- Background apps: 150Mb
When apps exceed these limits, the system triggers Low Memory Kill (LMK) event, crashing the app and disrupting user experience. High memory use also slows apps as the JS Thread spends more time on garbage collection (GC) cycles. To maintain a stable and smooth user experience, it’s important to:
- Monitor your app’s memory usage
- Identify objects consuming the most memory
- Eliminate unnecessary memory allocations
Q: How to investigate memory issues?
A: Use the following tools to detect memory issues:
-
Memory Monitor- Tracks real-time memory usage in your Vega app, showing when apps approach or exceed memory limits.
For details, see Inspect your app with the Memory Monitor.
-
Chrome DevTools (CDT) - Profiles JavaScript memory consumption, helping identify memory leaks through heap snapshots and allocation timelines.
For details, see Use Chrome DevTools for App Profiling.
-
Memlab - Identifies memory leaks by comparing heap snapshots across different user flows.
For details, see Analyze JavaScript heap snapshots.
-
Vega App KPI Visualizer - Helps in monitoring memory KPIs, such as foreground memory and background memory.
For details, see Measure App KPIs .
Q: How to mitigate memory issues?
A: Implement the following optimization strategies:
-
Clean up timers and listeners.
For details, see Listeners, event subscriptions, and timers.
-
Prevent closure scope leaks.
Closures that retain references to large objects cause memory leaks. The garbage collector can’t free these objects, leading to memory buildup. Regular cleanup ensures the garbage collector can free unused memory.
Example:
function leakyFunction() { const bigArray = new Array(1000000).fill(0); return function () { // bigArray is implicitly captured by the closure console.log("Hello, World!"); }; } leakyFunction(); // bigArray remains in memory even though it's no longer needed
Related topics
Last updated: Sep 30, 2025