Measuring performance impact of pagination in video apps
Tags: webrtc, ux, tutorial, performance
Published: 2023-10-10 16:58:29

_By [Olabisi Oduola](https://www.daily.co/blog/author/olabisi/)_

In our previous posts, we discussed how pagination can be used in a [custom Daily video chat app to support larger meetings](https://www.daily.co/blog/add-pagination-to-a-custom-daily-video-chat-app-to-support-larger-meetings/) and how to [manually manage media tracks in a paginated video call](https://www.daily.co/blog/optimize-call-quality-in-larger-calls-by-manually-managing-media-tracks-in-a-paginated-video-call-ui/).

Now, I will show you how to benchmark your pagination implementation and see for yourself how much impact it has on your app’s performance and user experience.

When building a custom video app with [Daily's Client SDK for JavaScript](https://docs.daily.co/reference/daily-js), developers can tailor their implementation to meet their exact product needs. This level of customization  creates the possibility for developers to impact the performance of their app (both positively and negatively) depending on how they decide to approach certain features, such as video tile pagination. This is an important consideration for any type of video call app, and one we can help you navigate. 

💡_If you are looking for a video call solution that is already optimized for various platforms and network conditions, check out [Daily Prebuilt](https://www.daily.co/products/prebuilt-video-call-app/)–our fully-featured video call embed._

One common question with building any custom video app is: How many video tiles should we show per page? This decision can have a significant impact on the application’s performance and user experience. 

If we show too _few_ videos per page, we may:

- Frustrate users: It can get annoying to click through many pages to find the participant video you are looking for, or miss out on some relevant or interesting videos.
- Compromise retention: Users may lose patience if they have to wait too long for the next page of videos to load.

On the other hand, if we show too many videos per page, we may:

- Decrease performance: Loading and rendering many videos at once comes with extra bandwidth and CPU consumption, which can slow down the app and degrade the quality of the videos over time.
- Clutter the visual field: Showing too many videos per page may create a crowded and overwhelming visual layout, making it tricky for users to find and focus on the content they are interested in.

Therefore, finding the optimal number of video tiles per page is a matter of balancing these factors. We need to find the “sweet spot” that maximizes both performance and user satisfaction.

That sweet spot is different for everyone. Different video apps have their own goals, constraints, and user flows. Therefore, we need to consider some factors that may influence this decision, such as:

- The nature of the app: Calls intended for smaller audiences, like small group classrooms or webinars, may be designed to support fewer, high-resolution video streams. Therefore, they may not benefit from pagination. On the other hand, if your app involves having many users interacting with each other, you will likely want to enable pagination. You’ll probably also experiment with bandwidth, output, and receive settings to sustain lively conversation in a larger group.
- The device and network conditions: The optimal number of video tiles per page may vary depending on the device and network capabilities of the users. For example, mobile devices have smaller screens, lower CPU power, and lower bandwidth than desktop devices. This may affect how many videos can be loaded and displayed effectively.

## How can you test and iterate on different pagination options?
We will use our existing [pagination demo app](https://github.com/daily-demos/track-subscriptions) introduced in a [previous post](https://www.daily.co/blog/optimize-call-quality-in-larger-calls-by-manually-managing-media-tracks-in-a-paginated-video-call-ui/), which allows you to control the number of video tiles shown in your app. We will utilize Chrome developer tools to compare the performance of different pagination scenarios.  We’ll then provide some tips on how to find the optimal balance between performance and user experience.

## Getting started
To follow along with this post, prepare your environment as follows:

1. Install [Google Chrome](https://www.google.com/chrome/) if you don’t already have it.
2. Create a free [Daily account](https://dashboard.daily.co/signup).
3. Retrieve your API key from the [developer dashboard](https://dashboard.daily.co/developers).
4. Clone the [`daily-demos/track-subscriptions`](https://github.com/daily-demos/track-subscriptions) repo from GitHub.
5. Navigate to the project directory and check out my `custom-tile-pagination` branch:
6. Install the necessary dependencies by running `yarn`
Create an `.env.local` file in the root directory of the app and add your own `DAILY_DOMAIN` and `DAILY_API_KEY` from your Daily account dashboard. Remember to never submit this file to source control! Your Daily API key is secret.

Finally, you can start the development server by running `yarn dev`

Open the app in Google Chrome by navigating to **http://localhost:3000/**

You can now create a new video call by clicking on the “Create room” button

![Entering a Daily video call room](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5w5vr13rhhu9a2xllqc.png)
_Entering a Daily video call room_

(Incognito Mode is preferable if you have a lot of extensions installed, it ensures that Chrome runs in a clean state as those extensions might create noise in your performance measurements.)

For the purpose of this article, I modified the [`hooks/useAspectGrid.js`](https://github.com/daily-demos/track-subscriptions/compare/custom-tile-pagination#diff-d0a1cd77dca25318be3c71a4b2f56c91cdca61b3997872a88339902808338439R17) file in the cloned app so we can pass in custom values for `customMaxTilesPerPage`. This determines the maximum video tiles to be displayed on each page.

```
export const useAspectGrid = (
  gridRef,
  numTiles,
  customMaxTilesPerPage = 20
) => {

    // ...Existing logic

    const MIN_TILE_WIDTH = useMemo(() => {
        const { width } = dimensions;
        const maxColumnsForCustomMax = Math.max(1, Math.floor(width / customMaxTilesPerPage));
        return width / maxColumnsForCustomMax;
      }, [dimensions, customMaxTilesPerPage]);

    // The rest of the hook…
}
```
With this modification, the tile width will reduce as the `customMaxTilesPerPage` value increases.

When you increase the value of `customMaxTilesPerPage` above, you are telling the `useAspectGrid()` hook (which creates the grid of video tiles to be displayed on a page) to display more tiles on each page. This means each tile will need to be narrower in order to fit into the available space. In the code above, I set the maximum tiles to display per page to 20. This means each participant will subscribe to the video and audio tracks of up to 20 others video call users.

Now, we can test the effect this will have on performance.

## Measuring the runtime performance of your pagination implementation using Chrome DevTools 
I will be using the Chrome DevTools performance monitor to visualize how our app performs during runtime and identify bottlenecks or other inefficiencies. The performance monitor  provides a real-time view of the runtime performance of the app by displaying graphs of various performance metrics that update in real time.

There are many metrics that can be used to measure the runtime performance of an app, but not all of them are relevant for our use case. For this Daily video demo app, we are interested in metrics that reflect how well the app handles multiple video renders, such as:

- **CPU**: The CPU metric shows how much processing power your app consumes.
- **JS heap memory**: This metric shows how much memory your app allocates and deallocates. (Check out my earlier post about [memory management](https://www.daily.co/blog/introduction-to-memory-management-in-node-js-applications/) if you want to learn more about how heap memory works.) 
- **FPS**: The frames per second (FPS) metric shows how smoothly your app renders on the screen. 
- **Network**: The network metric shows how much data your app transfers over the network. Daily also [monitors this](https://docs.daily.co/reference/daily-js/instance-methods/get-network-stats), dynamically adjusting call participants' receive settings to provide them with the [best possible experience](https://docs.daily.co/guides/architecture-and-monitoring/intro-to-video-arch) for their network conditions.

## Opening the performance monitor
First, open Chrome DevTools by using the shortcut Ctrl+Shift+I (Windows, Linux) or Command+Option+I (macOS).

In DevTools, on the main toolbar, select the “Performance monitor” tab. If that tab isn't visible, click the More tabs button, or else the More Tools button.

![Opening the DevTools performance monitor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k6coom4w9fr67vydo50u.gif)
_Opening the DevTools performance monitor_

To get the FPS readings, select the Rendering tool, and turn on Frame Rendering Stats. A new overlay will  appear in the top-left corner of your webpage. The Frame Rendering Stats overlay provides real-time estimates for FPS as your app runs. 

![20-tile in-app view with performance stats shown on the top left and right-hand sides](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2uh5vmcs0za3o62hdgps.gif)
_20-tile in-app view with performance stats shown on the top left and right-hand sides_

Based on the screenshot above, we can see that showing 20 video tiles results in a noticeable performance hit:

- The CPU usage reaches levels of 80-100%, indicating a considerable load that might result in overheating or battery depletion on the device.
- The memory consumption hovers between 80-100MB, displaying frequent fluctuations within the JavaScript heap graph.
- The frames per second (FPS) drops below 20, a level considered quite low, and can potentially lead to rendering issues such as stuttering or lagging.

![12-tile in-app view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5nlhvisqxg8bnwbwlrx.gif)
_12-tile in-app view_

When we switch to showing 12  tiles (which is the demo app’s default), we can see that:

- The CPU usage is around 10-20%, which is not too high for most devices.
- The application is using a moderate amount of memory (40-50MB). ​​This means the app is not creating and deleting too many objects.
- The FPS is around 50-60, which is ideal for a smooth rendering and smooth user experience. 

Therefore, we can conclude that _with no other changes to optimize output and receive bandwidth_, showing 12 video tiles is optimal for our app. Showing 20 video tiles concurrently, in this configuration, is suboptimal. Seeing the effect first-hand can help us optimize our pagination settings for the ideal effect. 

Of course, the number of video tracks being played is just one of several factors that have an impact on the app’s performance: a starting point. If your use case calls for playback of more (or fewer!) simultaneous video and audio tracks, you can then delve into Daily’s [send settings](https://docs.daily.co/reference/daily-js/instance-methods/update-send-settings#main) and [receive settings](https://docs.daily.co/reference/daily-js/instance-methods/update-receive-settings#main) options to fine-tune your configuration further.  

Let’s dig a little deeper into the different factors we’re using to judge the performance impact of our pagination configuration.

## CPU
CPU usage numbers may vary depending on the device, browser, network, and other factors, but we can use some general guidelines to help us get a gauge of how our pagination or other settings affect performance:

- We want to keep the CPU usage as low as possible to avoid overheating or draining the battery of the device.
- Ideally, you want to keep your CPU usage below 50% for a fast and responsive app.

Note that mobile devices have much less CPU power than desktops and laptops. Whenever you profile a page, use CPU Throttling to simulate how your page performs on mobile devices. To simulate a mobile CPU, you can use 4x slowdown for mid-tier devices or 6x slowdown for low-end mobile devices. You may find that a mobile app can benefit from subscribing to and displaying fewer video tracks than desktop. This can also be beneficial from a UI perspective, considering on mobile there’s not as much display space to work with.

## Heap memory
If your app is progressively using more and more memory, without it getting garbage collected, you have a [leak](https://www.daily.co/blog/introduction-to-memory-management-in-node-js-applications/). But leaks aside, how much memory usage is "too much"? There are no definitive numbers here, because different devices and browsers have different capabilities. JavaScript engines help us along with their own garbage collection processes. However, garbage collection itself can be an expensive operation.

In performance recordings, frequent changes (rising and falling) to the JS heap graphs indicate frequent garbage collection. This may be worth investigating, especially if you notice degraded performance on certain devices. 

## Frames per second (FPS)
A high FPS value means that your app is responsive and fluid, while low FPS can result in sluggish and choppy rendering. Ideally, you want to maintain an FPS of 50 or higher for a smooth user experience. The FPS is shown in the left-hand corner of your web app when the performance monitor is open.

## Conclusion
To achieve optimal performance and a great user experience in your video call application, focus on finding the right balance between performance and UX:

- [Consider device constraints](https://docs.daily.co/guides/architecture-and-monitoring/intro-to-video-arch#call-constraints-and-cameras): Account for CPU and bandwidth limitations on mobile and older devices. Limit active video cameras to maintain call quality.
- [Customisation](https://docs.daily.co/guides/configurations-and-settings/setting-up-calls#building-calls-with-daily-prebuilt): Tailor room settings to suit different use cases. Consider [Interactive Live Streaming](https://docs.daily.co/guides/scaling-calls/interactive-live-streaming-rtmp-output#main): For large audiences, consider live streaming with minimal delay to enhance performance. Daily’s ILS supports 100,000 real-time participants. 
- [Find your sweet spot](https://docs.daily.co/guides/configurations-and-settings/setting-up-calls#building-a-custom-video-call-ui-using-the-daily-call-object): Find your ideal balance of pagination settings and media resolution to suit your specific use case.
- Look at your app holistically: Video is likely just one part of your application. Be aware of other components that may impact the performance of your application in conjunction with the video implementation.

By taking these performance considerations into account, you can create a video call app that delivers both top-notch performance and an enjoyable user experience.