as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

Vega Web App Performance Best Practices

Having a performant app is essential for building something customers love to use. Monitor performance throughout the development process. There are two key measures of latency: time to first frame (TTFF), and ready to use (RTU), also called time to fully drawn (TTFD). The following are some common best practices to improve app performance.

WebView KPI measurements

Use the Native SplashScreen API

App launch performance impacts the customer experience. When a customer launches an app, they expect to see something on the screen almost immediately. How fast that occurs is the TTFF (Time to first frame). Vega Script's native SplashScreen feature provides the ability to display an app specific splash screen using image assets, so users will see the splash screen immediately when your app launches. Your app can then focus on loading content and making network calls, without wasting time rendering a JavaScript-based splash screen. You can include animation effects with a series of animated images for the splash screen.

This KPI is calculated as the time it takes after the main component in the manifest.toml file is launched, to the time when it renders its first frame on the screen.

WebView splash screen

The SplashScreenManager enables you to build static or animated graphics for the screen until you progress to the next screen of your app. The SplashScreen assets are bundled during packaging of the app, and used by the device during app launch. SplashScreen removes some of the startup complexity while your app launches, so the startup screen will display until you remove it when your app is ready for its first frame.

Implement a TTFD (Time To Fully Drawn) marker

Vega apps are expected to meet certain performance markers during phases of the app lifecycle. One marker is TTFD (see previous image), which apps are expected to meet once the app has successfully loaded and is ready for customer interaction. This is applicable for cool start, when the app process doesn’t yet exist, and warm start, when the app process already exists. Web apps should implement this marker in onLoad callback when the web app content is loaded fully.

Call the useReportFullyDrawn() method when the web app has been launched and loaded. The wrapper has an onLoad event which will be triggered when the app is launched and ready. Also, call the reportFullyDrawn() method when it moves from the background to the foreground during a warm launch.

This example code calls useReportFullyDrawn(), to handle both cold start (onLoad) and warmStart (keplerAppState).

Copied to clipboard.

import { useReportFullyDrawn } from '@amazon-devices/kepler-performance-api';
import React, { useEffect, useState, useRef } from 'react';
import {VegaAppStateChange, useAddVegaAppStateListenerCallback, useGetCurrentVegaAppStateCallback} from '@amazon-devices/react-native-kepler';
...
...
export const App = () => {
    const reportFullyDrawnCallback = useReportFullyDrawn();
    const getCurrentVegaAppStateCallback = useGetCurrentVegaAppStateCallback();
    const addVegaAppStateListenerCallback = useAddVegaAppStateListenerCallback();
    const [appState, setAppState] = useState(getCurrentVegaAppStateCallback);

    // Using a useEffect Hook to have the fully drawn reporting performed 
    // post first render and when the state changes to foreground
    // If the app performs additional asynchronous processing
    // that needs to be completed before it is fully drawn pass the
    // completion state in the array of dependencies and check the state
    // inside the hook.
    useEffect(() => {
        const changeSubscription = addVegaAppStateListenerCallback(
            'change',
            handleAppStateChange
        );
    }, [reportFullyDrawnCallback]);

    const handleAppStateChange = (nextAppState: any) => {
        if (
            appState.match(/inactive|background/) &&
            nextAppState === 'active'
        ) {
            reportFullyDrawnCallback();
        }
        setAppState(nextAppState);
    };
    ...
    ...
    return (
        <View style={styles.sectionContainer}>
      <WebView
      .
      .
      .
      onLoad={(event) => {
          console.log("onLoad url: ", event.nativeEvent.url)
          // Hide the splash screen and render content
          SplashScreenManager.hideAsync(your.package.name).catch((e) => {
            console.error("Error while hiding splash screen: " , e) });
          // Report fully drawn only for actual page is loaded
          if("https://mywebapp.com/home" === event.nativeEvent.url)
          {
            reportFullyDrawnCallback();
          }
        }}
        />
    </View>
    );
};

For more details, see How to implement reportFullyDrawn marker for Webview Apps.

Optimize network requests

To improve web app launch performance, you must optimize network requests. One way to do this is to minimize HTTP requests by combining CSS and JavaScript files where possible, using image sprites, and reducing the number of external third party dependencies. Enabling asset compression using Gzip or Brotli significantly decreases the payload size for text-based resources like HTML, CSS, and JavaScript. Keep in mind that image files are typically already compressed, so they don’t benefit from this.

Copied to clipboard.

<!-- Inefficient and may not be needed for all cases --> 
<script src="utils.js"></script> 
<script src="api.js"></script> 
<scriptsrc="main.js"></script>

<!-- Optimized - as long as it can be logically combined -->
<script src="app.bundle.js" defer></script>

Leveraging modern HTTP protocols such as HTTP/2 or HTTP/3 is also beneficial, since they support multiplexing and minimize overhead by allowing multiple requests to be sent concurrently over a single connection. Reducing client-side redirects also helps eliminate unnecessary latency, since every redirect adds an extra round-trip, delaying the page load.

Reduce server response times

Optimizing server response time is crucial for delivering a fast and responsive user experience. One of the most effective strategies is to use a Content Delivery Network (CDN), which serves static assets like images, JavaScript, and CSS files from edge locations geographically closer to the user, reducing latency. Reducing Time to First Byte (TTFB) by optimizing backend processing, such as improving database queries, reducing middleware overhead, and optimizing server logic, can greatly improve performance.

API efficiency plays a role as well. Minimizing the number of API calls, combining them when appropriate, and avoiding redundant requests can reduce network overhead. For faster content delivery, consider using Server-Side Rendering (SSR) or Static Site Generation (SSG), which pre-renders HTML on the server, allowing faster page loads and improved First Contentful Paint (FCP). FCT is how long it takes for a browser to render the first piece of content. You can also defer loading non-critical or secondary data by using lazy loading techniques to prioritize the most essential content first.

Optimize rendering and JavaScript execution

Optimize rendering and JavaScript execution for fast and responsive web apps. One key practice is to avoid blocking the main JavaScript thread with heavy computations or unnecessary logic during page load. When the main thread is blocked, it may delay rendering with frame drops, negatively impacting the user experience.

To mitigate this, keep JavaScript lightweight and execute only the essential code during the initial load. This applies to input event handling as well. Input handlers may cause performance problems in your apps fluidity, since they can block frames from completing, and cause additional and unnecessary layout work. Debounce your handlers, meaning store event values and deal with style changes in the next requestAnimationFrame callback.

Load scripts asynchronously that are not immediately necessary using the async or defer attributes to prevent them from blocking page rendering. This reduces the impact of render-blocking JavaScript.

Copied to clipboard.

// Asynchronous JavaScript loading
<script src="analytics.js" defer></script>

// Dynamic data/JavaScript importing when required
import('./data.js').then(initData);

Code splitting can load JavaScript modules dynamically, so each page or feature loads only the scripts it needs. Enable acceleration through CSS properties like transform and will-change for smoother animations and better visual performance. GPU acceleration through CSS helps offload rendering to the GPU. These strategies enhance web app perceived and actual performance.

Web Workers are another way to optimize your JavaScript, allowing it to run in the background. For more information, see Vega Web App Best Practices - Web Workers.

Cache resources

Caching enhances the performance and responsiveness of web apps. Client side caching involves setting appropriate Cache-Control headers for resources such as JavaScript files, CSS stylesheets, data, and images. This allows web app to store and reuse these assets instead of downloading them repeatedly. Leveraging CDN caching can also greatly improve load times by serving static content from edge locations closer to the user. By combining client and CDN caching, developers can reduce server load, decrease latency, and provide a smoother experience for end users.

Improve scroll performance

There are several areas to consider for improving your app’s scroll performance. First, avoid frequent access or changes to layout properties, such as offsetTop and scrollHeight within scroll event handlers. Making these changes will impact performance, since the layout must be recalculated each time. You can also throttle or debounce mechanisms to limit the frequency of scroll event handling. It’s best to avoid synchronous layout reads or writes inside scroll listeners to prevent forced reflows.

Only render visible or necessary elements, rather than everything on the page, or an entire scrollable list. It’s also a good idea to use GPU-accelerated CSS properties like transform for smooth scrolling instead of CPU-heavy ones like top, left, or width.

The Rendering tab in Chrome DevTools provides visual cues to highlight layers that paint slowly or redundantly while scrolling. Use this tool to identify performance bottlenecks and optimize your scroll behavior.

Measure your web app’s KPI’s

Vega provides a Vega App KPI Visualizer tool to measure the key performance metrics at a high level. Use this tool to measure Time To First Frame (TTFF), Time To Fully Drawn (TTFD), scroll fluidity, and video fluidity metrics. For more details, see Measure App KPIs.

To view more detailed, lower level performance aspects of your web app, Chrome Dev Tool (CDT) will show you lower level performance aspects of your web app. Some Chrome tools include the Performance Tab, Network Tab, and Lighthouse to audit benchmarks, and identify web app hotspots (HTML/JS/CSS/Images) so you can improve your app’s performance. LightHouse does not currently work in Vega, so you can load your web app directly in Desktop Chrome and debug with the appropriate network and cpu restrictions.


Last updated: Sep 30, 2025