How Disney+ Hotstar increased weekly card views by 100% on living room devices by reducing INP by 61%

Improving Interaction to Next Paint (INP) on smart TV and set-top box devices presents considerably more challenges than for desktop browsers, owing to the constraints of limited API support and modest system specifications. In this case study, you'll find out how Disney+ Hotstar successfully addressed these obstacles, and gained significant business benefits as a result.

Bhuvaneswaran Mohan
Bhuvaneswaran Mohan
Saurabh Rajpal
Saurabh Rajpal

With the increased adoption of living room devices, Disney+ Hotstar recognized that providing a seamless browsing experience in their app for smart TVs and set-top boxes is a critical business requirement. What makes it harder to fix INP for such devices, though, is that any given TV model may use very old browser versions—for example, a 2020 LG TV uses Chrome 68 released in 2018. Some of these devices can be categorized as low-end-devices too, meaning that they can't respond to interactions as quickly as flagship tablet and laptop devices.

The following figure compares how much time it takes to load a page, between a laptop with its CPU slowed down by six times applied in Chrome DevTools and a smart TV. As can be seen, the laptop is still much faster than a recently manufactured smart TV.

A screenshot of the performance profiler in Chrome DevTools profiling the loading performance of the Disney+ HotStar app on a laptop. A custom metric named PAGE_RENDER_TIME comes in at 1.39 seconds.
Profile (1.3s Page render time) from laptop with a 6x CPU slowdown to mock TV browser configuration. The PAGE_RENDER_TIME is a custom metric used to capture the time taken between showing the first component of the page and HTML parsing completion.
A screenshot of the performance profiler in Chrome DevTools profiling the loading performance of the Disney+ HotStar app on an actual Smart TV device. A custom metric named PAGE_RENDER_TIME comes in at 6.47 seconds.
Profile (6.47 second page render) from an actual TV using remote debugging with TV app running in Chrome.

While these tests yield lab data, Disney+ Hotstar started to collect field data for Interaction to Next Paint (INP) from their app's actual users using the web-vitals library, and observed 75% of the app's users experienced an INP of 675 milliseconds in the field, which is considered a "poor" user experience according to the INP thresholds.

This case study covers how Disney+ Hotstar improved responsiveness in their streaming applications, especially on the low-end devices. They achieved a 61% improvement by bringing INP values down to 272 milliseconds—still above the recommended "good" threshold of 200 milliseconds, but a substantial improvement towards that.

The findings

Disney+ Hotstar instrumented the app using the onINP method from the web-vitals library's attribution build. During the initial phase, various challenges were encountered, especially in identifying the precise target element. The issue arose because all references pointed to the body due to a third-party spatial navigation library which was used with some customizations in the Disney+ Hotstar app. This library solely listens to events on the document body and subsequently determines the actual focused element and predicts the next focus based on remote key presses.

Disney+ Hotstar began by first solving the attribution issue so that interactions responsible for high INP values could be properly identified. For this, Disney+ Hotstar logged the focusKey attribute which is present already in the spatial navigation library for the currently focused element as well as map of all focusable elements on the page, which is analogous to the interaction target available in the web-vitals attribution build.

A screenshot of a list of elements, according to their focusKey attribute, along with the interaction latency for each.
Capturing focusKey, along with path to the element triggering it.

Now with appropriate measurement and attribution in place, findings from field data reported the following interactions as the most problematic for INP:

  1. Horizontal carousel tray navigation.
  2. Vertical carousel tray navigation.
  3. Interactions during initial page load.
A screenshot of the element responsible for tray carousel navigation by its focus key.
Dashboard entry showing contribution to INP by tray carousel navigation.

Upon profiling these interactions with the performance panel in Chrome Dev Tools, it was realized that the spatial navigation library read the position of all the focusable elements and built a new tree. This is an expensive operation that triggers layout thrashing on each interaction, such as moving from one element to another.

For the home page, a tree was generated by the spatial navigation library as follows:

An example tree generated by spatial navigation library. Below the root are Navbar and Tray Container nodes. In particular, the Tray Container node contains three card nodes, each of which have numerous subnodes that contribute to a large DOM size.
Previous spatial navigation tree for the home page.

This meant that, if the app displayed 10 trays, and each tray had 7 cards, there would be 70 focusable elements for the tray container, including navigation items. This is a high number of interactive elements. A third-party carousel library was also used, which read the dimensions of each card during horizontal navigation to translate the container, adding even more interaction latency.

Fixing the problems

There were several different problems that all had to be tackled separately to resolve the responsiveness issues of the overall app.

Horizontal tray navigation improvements

Disney+ Hotstar built their own in-house carousel library which does not trigger layout thrashing by using composited animations and reading the dimensions once per tray, rather than once per card.

The spatial navigation focuses only on the root of the carousel, and for further horizontal navigation, our custom carousel comes into the picture. With this approach, Disney+ Hotstar removed the dependency of spatial navigation and the old carousel library which was reading the dimensions on every navigation.

This is how the spatial navigation tree looked after these optimizations.

An example optimized tree generated by the spatial navigation library, which is significantly optimized over the prior version, containing far fewer nodes.
Spatial navigation tree after optimization.

The following images are a performance comparison measured in the performance panel of Chrome DevTools before and after our carousel implementation.

A screenshot of the performance panel in Chrome DevTools for the tasks the third-party carousel kicks off. There are numerous long tasks that delay interactivity.
Third-party carousel.
A screenshot of the performance panel in Chrome DevTools for the tasks the in-house carousel kicks off. Compared to the third-party carousel, there are far fewer long tasks, allowing interactions to occur more quickly.
In-house carousel.

As a result of this work, Disney+ Hotstar saw significant reduction in their app's INP in the field. They also managed to save around 35 KB (compressed) by removing the third-party library. As a bonus, these improvements also allowed Disney+ Hotstar to reduce duration of their custom metric which they use to measure total rendering time for the home page, as layouts are triggered less often due to reduced spatial navigation nodes.

A time series of the page render time custom metric for both tizentv and webos, which decreased both 31% and 25.2% respectively starting from the March 13th to March 19th timeframe.
Downward trend for page render times by TV OS (Samsung-Tizen and WebOS-LG).

Vertical tray navigation improvements

Disney+ Hotstar also improved vertical tray navigation performance by lazy loading the trays instead of loading all of them up front. So on page load, instead of loading 10 instances of the tray—which internally, each have a carousel component and a bunch of images—the app loads only the two trays which are visible in the viewport, plus an additional tray above and below. The rendering was also split up into multiple tasks using the setTimeout() yielding strategy so that the main thread has more opportunities to handle user interactions.

A stylized visualization of tasks for running event handlers and rendering updates. The rendering updates are postponed after a single long task.
A single long-running task followed by rendering before vertical tray improvement.
Another visualization of the same activity as the prior figure, but tasks are broken up due to yielding, which allows rendering to occur sooner.
Multiple split tasks after vertical tray improvement, with opportunities for rendering in between the split tasks.

Interactions during initial page load

INP will be high for applications that process a huge number of scripts during app launch. This is because the browser has to download, parse, and evaluate those scripts. While this all happens, the main thread will be occupied for a potentially long time, and unable to quickly respond to user interactions.

Disney+ Hotstar realized they were processing more scripts than were actually necessary during application start (the splash screen time) to make future page loads faster. This incurred additional script evaluation tasks, which also had the potential to negatively affect INP.

To fix this, Disney+ Hotstar considered dynamically loading most of the assets, so that they would save time during app startup. However, doing so would have increased load times for navigations to future pages, since that JavaScript would no longer be loaded in advance with this change. To tackle this, Disney+ Hotstar developed an in-house asset preloader library which determines which page might come next in the user journey, and will preload assets for that page. For example:

  • When a user is on the login page, the asset preloader library will preload assets for the profile selection page.
  • On the profile selection page, home page assets are loaded.
  • On the home page, the details page's assets are loaded.
  • Finally, the watch page's assets are loaded on the details page.

Optimizing asset loading helped Disney+ Hotstar with two things: reduce the app's INP (as the main thread was now relatively free to execute user interactions), and also reduce memory usage on low-tier devices.

These changes led to 32% decrease in the reported INP number from the field as can be seen in the following screenshot.

A time series of INP values beginning August 13th and September 11th. Over this period, a 32% reduction in INP is shown.
INP reduction for tray improvements.

Other improvements

Disney+ Hotstar also figured out there were long tasks on a few user events which could be split by yielding to the main thread often, and went one step further and created a task generator utility which will allow users to cancel the task in the middle of its execution.

For example, when the user navigates through multiple cards on the tray, the following happens:

  • The next card is focused.
  • The card is translated if it needs to be.
  • Spotlight is updated.
  • The trailer—if present—is fetched and the playback is initiated.
  • Analytics events are fired for the action.

If, during this process, the user focuses on the next card, then the rest of the steps wouldn't need to be executed. For example, trailer fetching and player initialisation for a particular title would no longer be needed if the user has moved on to the next card. Hence, those tasks can be aborted to free up the main thread.

Disney+ Hotstar's task generator utility accepts a function which is a task, and when another task comes in the middle, the previous task is aborted saving us unnecessary task execution and quickly act on the necessary task.

Results

Overall, Disney+ Hotstar's application INP dropped from 675 milliseconds to 272 milliseconds, representing an improvement of nearly 60%! In addition, the tray interaction latencies in particular decreased from around 400 milliseconds to about 100 milliseconds.

A timeseries INP values beginning August 23rd to September 21st. A 61% reduction in INP was realized in this timeframe.

The business impact: weekly card views increased from 111 to 226 per user! That's a 100% increase, showcasing that a faster and more responsive interface are more likely to engage users for longer periods of time.

A screenshot of a time series showing a 100% increase in weekly card views on the Disney+ HotStar app for both tizentv and webos. The increase occurs very sharply after April 4, 2004.

This is just the beginning, and Disney+ Hotstar has only scratched the surface of improving rendering and interaction performance with the INP metric as their guide, And their team is excited to make Disney+ Hotstar a buttery smooth experience for their customers in the near future.

Thanks to Ayush, Ajay, Kiran, Milan and Richa from Disney+ Hotstar for their efforts to turn the tide over.

Special thanks to Ankeet Maini, Engineering Head Disney+ Hotstar, and Rahul Krishnan P, Head of Customer Experience Disney+ Hotstar to support this innovation work, and to Jeremy Wagner, Gilberto, Barry Pollard, and Brendan Kenny from Google for reviewing and helping with publishing this case study.