Fine-Tuning React.js for Smart TVs

Imagine building a Smart TV application to stream movies. All web-based smart TV apps require a Document Object Model (DOM) manipulation framework to apply logic on what to render.

Besides this, the other vital components that make it a complete user experience or solution are:

  • CSS for defining how it should render and all the related animations and effects
  • Video player libraries which enrich the basic HTML video player

In this article, let’s focus on the DOM manipulation library. Without an efficient library, you might experience slow responsiveness. That’s where React comes in. React’s modular approach and virtual DOM offer a promising solution for Smart TV applications. By utilising React’s strengths, developers can create smooth interactions even on devices with limited resources. This concise guide explores challenges posed by processing or memory constraints and provides actionable strategies to enhance React application performance.

Why React for smart TVs:

React is often considered one of the best choices for Smart TV app development, among other JavaScript frameworks, due to several reasons:

  1. Component-based architecture: React is built around the concept of reusable components. This makes it easier to break down your user interface (UI) into smaller, manageable pieces, which is particularly useful for building complex UI for Smart TV apps. Components in React are highly modular, promoting code reusability and maintainability.
  2. Memoization: React’s memoization feature enables you to optimise the rendering process by memoizing (caching) the results of expensive function calls. This is particularly beneficial for smart TV apps where resources are limited, and rendering efficiency is essential.
  3. Virtual DOM: React utilises a virtual DOM, which is an in-memory representation of the actual DOM. This allows React to efficiently update the UI by only rendering the components that have changed, minimising DOM manipulation and enhancing performance. For Smart TV apps, which may run on devices with varying processing power, this optimisation can be beneficial for smooth performance.
  4. JSX Syntax: React’s JSX syntax allows you to write HTML-like code directly within your JavaScript files. This makes the code more readable and intuitive, especially for developers familiar with HTML. JSX also enables you to seamlessly mix HTML markup with JavaScript logic, simplifying the creation of UI components. And these help in the long term maintenance of the app.
  5. React native: While Smart TV apps primarily use web technologies, React’s ecosystem extends beyond web development. React native, a framework based on React, allows you to build native mobile apps for iOS and Android using JavaScript. If you ever decide to expand your app to other platforms, having experience with React can be advantageous.
  6. Community and ecosystem: React has a large and active community of developers, which translates to extensive documentation, tutorials, and third-party libraries. This can be invaluable when you encounter challenges during your Smart TV app development, as you are likely to find solutions, resources, and community support readily available.

While React offers many advantages for Smart TV app development, it’s important to consider your specific project requirements, team expertise, and familiarity with other frameworks before making a decision. Ultimately, the “best” framework depends on how well it aligns with your needs and preferences. Any framework will need to be optimised by the application to ensure the best possible performance on TV devices.

Here is a standard movie catalog page from a non optimised React streaming application. The highlights indicate when elements are re-rendered as the user shifts focus from one movie card to another. Notice that all the movie cards in the three rows are re-rendered unnecessarily.

Let’s further analyse the common pitfalls and the React concepts that could be utilised better below.

Virtual DOM and reconciliation

The virtual DOM (Virtual Document Object Model) is a programming concept in which a “virtual” representation of a user interface is preserved in memory and synchronised with the browser’s DOM via the react library.

Leveraging React’s virtual DOM reconciliation algorithm can minimise unnecessary DOM updates and enhance performance. By ensuring that only the relevant portions of the DOM are updated when state or props change, React can optimise rendering and improve the responsiveness of the application.

Imagine you are presented with a <Spinner> indicating that the movie list is being fetched. Once the fetch is successful, the <Spinner> is replaced by the <Movies> component, which organises the movie list into rows and columns for display. React destroys the <Spinner> component and constructs the <Movies> component to render the movies.

Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. Going from dom elements like <a> to <img>, or from react components like <Movie> to <Interview>, any of these will lead to a full rebuild of the subtree.

Imagine you are navigating through a list of movie recommendations on your Smart TV. Each movie card is rendered using a separate component <MovieItem>:

<MovieItem title="Inception" focused={true} /> 

<MovieItem title="The Shawshank Redemption" focused={false} />

<MovieItem title="The Dark Knight" focused={false} />

React, being smart, will only update that specific movie component that is losing the focus and the next one that is getting the focus, not the entire list.

In summary, when the type of an element changes in React, the old element is dismounted and the new element is mounted in its place. React’s reconciliation process ensures that changes are accurately reflected in the UI, while lifecycle methods and clean-up operations are appropriately handled during this transition.

However, in the example above, the entire list of movies undergoes re-rendering. Let’s investigate the reasons behind this behaviour.

Common Pitfalls

Performance-related changes applied incorrectly can even harm performance.

“God” components

A “God component” is a React component that takes on too many responsibilities, becoming a central hub for various functionalities. Such components tend to grow in complexity and size, making them difficult to manage, debug, and maintain over time. This can have a cascading effect on the entire application’s performance, codebase, and development velocity.

Any state or prop change in such a component will trigger a complete re-render of all the elements defined within the component.

Lack of memoization of components and computed value

We have observed that as focus transitions occur, the entire movie list undergoes re-rendering. Such unnecessary re-renders of components should not happen when the state of the parent component, responsible for holding the current focus index, changes. This is where memoization becomes crucial.

1. React.memo:

const Movie = React.memo(({videoData, focused}) => {
          // Render video thumbnail...
          return '...';
}, areEqual);

function areEqual(prevProps, nextProps) {
          return true; // trigger render
          return false; // trigger render
}

By using React.memo, you are telling React to memoize this component. It will only re-render if the videoData or focused prop changes. The optional second parameter, areEqual can be utilised to add custom checks during the decision-making.

2. React.useMemo hook:

In functional components, the useMemo hook is employed to memoize the result of a function or value computation. It’s beneficial when there’s a need to compute a value based on props, but only when those props change.

const valueMemoized = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Inline function definitions

Imagine you have a button that allows users to add a Movie to their Watchlist.

return (
         <div>
                  <Button onClick={() => API.addWatchlist(videoId)}>Add to Watchlist</Button>
    </div>
);

In this case, the inline function definition for onClick can create a new reference when the parent re-renders, leading to unnecessary re-renders of the Button component. You can optimise this by memoizing the callback function using React.useCallback:

const handleClick = useCallback(() => {
         API.addWatchlist(videoId)
}, [])
return (
         <div>
                  <Button onClick={handleClick}>Add to Watchlist</Button>
         </div>
);

By using useCallback hook, you ensure that the handleClick function remains the same across renders, preventing unnecessary re-renders of the component <Button>.

Significance of the key prop in React arrays

The key prop in React holds significant importance when rendering arrays of components. It serves as a unique identifier for each component, impacting performance, reconciliation, and rendering efficiency.

Example:

function Row({ movies }) {
     return (
         <div>
              {movies.map(movie => (
                  <MovieItem key={movie.id} data={movie} />
               ))}
         </div>
     );
}

In the example, movie.id serves as a key, enabling efficient updates when the movies array changes.

In essence, the key prop is pivotal for React’s efficiency, performance, and maintaining consistent UI rendering in arrays of components.

Using array indices as keys in React

Using array indices as keys might seem convenient, but it can lead to issues when you reorder or modify the array.

Let’s rewrite the above example with the array index as Key to render the watchlist.

function WatchListRow() {
     const movies = ["The Shawshank Redemption", "The Dark Knight"]
     return (
          <div>
               {movies.map((movie, idx) => (
                    <MovieItem key={idx} data={movie} />
                ))}
         </div>
     );
}

Imagine you added an item to the first position of the array.

const movies = ["Inception", "The Shawshank Redemption", "The Dark Knight"]

React gets confused because it relies on the index as the key and behaves like the new item is added to the bottom of the array.

React may incorrectly identify components as unchanged, or remove and recreate them unnecessarily.

Here is a further optimised iteration of the movie catalog page, with minimal component re-rendering:

In conclusion, React is a powerful tool for building Smart TV applications, but understanding its concepts and best practices is crucial for optimal performance, especially on low-end TV devices. Through concrete examples, we have illustrated how React’s reconciliation process, memoization, key props, and proper resource management can enhance the user experience on Smart TVs. With these techniques, you can create responsive, efficient, and engaging Smart TV apps that make the most of limited processing power, and enrich the living room entertainment experience.

At DIAGNAL, our mission is to deliver awesome experiences for our customers and to continuously develop ourselves. We have a strong commitment to efficiency, trust and flexibility, and work with major media companies around the world, including Celestial Tiger Entertainment, Intigral, LoungesTV, Optus Sport, WRC Promoter and more. 

To find out more about how we can help, please reach out to us.

Recent Posts

Sky Stream vs EE TV: The Battle for UK Super Aggregation market

This blog will explore the two other strategies, Digital watermarking and Content fingerprinting, which are integral components within the broader landscape of DRM systems and tokenisation, and play pivotal roles in safeguarding intellectual property and ensuring content integrity.

More on OTT Apps

5 Essential Features for OTT Streaming Apps

Maintaining a good user experience A premium streaming app experience is more than just branding, design, usability and function. The key fundamental of creating an high-end user experience is understanding the user and their engagement points within the app. We will talk about the 5 essential product features for OTT apps on the market today and why they are important

Reducing Churn Rate With Offline Playback

The Benefits of having Offline playback for End-users and Content Providers     Introduction Offline Playback is a high-end feature for OTT Applications. Allowing end-users to download DRM/Non DRM videos over WI-FI and/or Mobile Data Networks has been proven to increase user engagement and reduce churn rate for content providers. Whether the user is commuting to work, flying or simply

Subscribe to our Newsletter

Want to keep up to date with all our latest news and information? Enter your email below to be added to our mailing list.