Back to posts

Improving Page Load Time with the AsyncSelectField

Dinosaurs in drumheller

The select component is an integral part of most frontend applications, especially if they involve taking user input via forms. It presents users with a list of options to choose from when entering data. This helps reduce errors by avoiding manual typing of the data and simplifies the user experience since all they need to do is click on the right option.

However, a downside of the select component is that it doesn't optimize performance when loading and displaying data.

In this article, you'll learn about the AsyncSelectField, a new variant of the select component that offers better performance and overall user experience compared to the standard select component.

Issues with the Regular Select Component

The regular select components are great for presenting users with options to choose from when entering data. However, they work best with client-side, static data that are usually small in size. When there are too many options or the options need to be fetched from a database, regular select components can present a few issues.

Loads All Options at Once

The regular select component does not offer any dynamic loading of options. This means that all options must be loaded and set before the select component can be used. If data is fetched from remote sources, the availability of your select component depends on the size of the data set and the network speed.

Apart from that, loading all options at once usually means that users will see a long (and complete) list of options to choose from. It can be quite tedious for them to search through such a long list manually to find the one that they want to select.

Paginated Endpoints Need Multiple Chained Requests to Load Everything

If the data source of your select component offers a paginated endpoint, a regular select component will require you to query all data page by page across multiple requests. This means that not only will you query a large remote data set, but you will also make multiple requests chained one after another, adding to the performance overhead. You could write some JS code to dynamically load and add options to the select component, but that adds more complexity to your codebase. One way to avoid this is by restructuring your endpoint to return the data all at once. However, that approach is counterintuitive since the entire point of pagination is to improve performance when querying data from large data sets.

You can consider updating your endpoint to return cursors for the next and previous pages of data instead of relying on offsets if you haven't already. This will remove dependency on your frontend to properly chain and coordinate multiple requests. You can simply make another request if there's a next-page cursor.

Introducing the Sous Chef AsyncSelectField Component

To solve these problems and present an overall better experience for end users, 7shifts came up with the AsyncSelectField component in their Sous Chef design system. The AsyncSelectField component looks and feels the same as a regular select field, as can be seen below:

Async and regular select components

However, the fundamental difference between the two components lies in how they fetch their options. While the regular select component requires that all options be fetched, preferably at the time of render, the AsyncSelectField allows users to search through the options which then only fetches the data needed.

The ideal way to use the AsyncSelectField component is to load a small list of default or most commonly used options on render and then allow users to enter the initial characters of any option that they'd like to choose that isn't available in the list shown to them. This approach provides your users with a quick, concise list to choose from while saving on enormous load times.

The AsyncSelectField tackles the problems with a regular select component in two ways. Firstly, it doesn't load all the data at once. The search functionality automatically removes irrelevant options from the list, so the data that you download is small and relevant to your user's needs.

Secondly, a paginated API does not require you to chain requests anymore. If the number of matching options for a search query is more than the set page size of the API, you can simply prompt the user to continue typing to load more options.

This is how you can implement an AsyncSelectField component to fetch options data from an API and update them based on user input:

Benefits of Using the AsyncSelectField over Regular Select

Using the AsyncSelectField rather than a regular select component has several benefits in certain scenarios.

Performance Improvements

The biggest benefit of the AsyncSelectField over regular select fields is improved performance at scale.

As an example, let's take an employee database that has around 6,600 records, with each record around 6 KB in size.

When a regular select field loads this data using paginated endpoints, here's how it goes:

Normal select field

You can see that the drop-down list contains way too many options to scroll down easily and find the right one. The total loading time of the page is also longer (close to 1.1 seconds) than what would be acceptable, and a whopping 42.9 MB of data was downloaded from the server.

Note: Please keep in mind that the server and the data store used in this test are local to the React app. In average real-world cases, fetching more than 40 MB of data over the internet would take a lot longer than this.

Now let's see how the AsyncSelectField performs with the same data set:

Async select field

As you can see, the load time is almost two-thirds faster, taking just 35% of the time it took in the original approach, while downloading only 10% of the original amount of data (just 4 MB). You can even reduce this further by reducing the number of options that are to be fetched upon the initial render.

No chained calls are needed to be made, and a short initial list of options means the user can easily navigate through the list. If they don't find what they're looking for, they search for it by typing in the text box.

Search Instead of Scroll

When you're working with large data sets, it can become quite tedious to scroll through hundreds of options to find the one that you need to select. Choosing from ten options makes sense, forty options are still doable, but finding an option among hundreds means your users will need to slowly and carefully scroll through a long list to find what they're looking for.

A simple search like that of the AsyncSelectField can help you improve user experience by allowing them to find their desired option by typing its initial letters. Typing out a few initial letters of the option you're looking for is likely to narrow your list down to under 5 to 7 percent of the original size. The options shown to you will also be relevant and similar to what you're looking for.

One downside of searching instead of scrolling is that users might make a typing mistake. They would then be presented with irrelevant options or, in some cases, no options at all, which is a bad user experience. However, this has only been observed in 3 percent of cases so far. So while typos are an issue, they're rare enough not to cause major discomfort to users.

When to Use the AsyncSelectField vs. Regular Select

Obviously, using the AsyncSelectField isn't always the preferred choice.

It makes sense to use it for implementing a drop-down list when the size of your options list is large and its data source is remote—i.e., queried over a network. You could also consider using the AsyncSelectField if your data source is local but you'd like to allow your users to be able to search through it without writing extra code for the UI implementation of the search feature.

However, if your list of options is small and static and does not require search functionality, you can stick to the regular select option to avoid having to write a loadOptions function.

Using a simple fetch command to get the options and load them in the regular select component also makes sense in some cases where the data is being loaded over a network but is small in size (less than fifty records and all in one request).

Final Thoughts

While the select component is a great approach to handling form data input, it can be slow at scale. If you have to render a long list of options and allow users to comfortably find the option they need to select, you need something different. The AsyncSelectField component by Sous Chef fits the bill perfectly.

In this article, you learned how the AsyncSelectField component solves the issues with the regular select field and how you can get started with it. Make sure to check out Sous Chef, an all-new design system by 7shifts that offers the AsyncSelectField component and much more.