Asynchronous UX

Rate this content
Bookmark
The video discusses Asynchronous UX in React, particularly for single-page applications. It emphasizes the importance of progress indicators, skeleton screens, and handling error states to enhance user experience during data fetching. The video explains how to prevent flickering effects by introducing delays before showing progress indicators. It also covers the use of idempotency keys to prevent duplicate actions in scenarios like payments or bookings. The talk highlights the challenges of managing long-running actions and the importance of handling backend errors and empty states effectively. It provides examples of responsive UI design, such as disabling buttons to prevent double submissions and using optimistic updates for immediate UI responsiveness.

From Author:

"Please do not close or leave this page" may send shivers down your spine, but coding the proper UX flow for async might make you question your daily job. How can we properly handle UX for asynchronous code in highly responsive applications? Let's explore how introducing asynchronous code creates a challenge for UX.

This talk has been presented at React Advanced Conference 2021, check out the latest edition of this React Conference.

FAQ

Asynchronous UX in React refers to user interface patterns that handle the asynchronous nature of web applications, such as waiting for server responses or handling data fetching delays without blocking user interactions.

Single-page applications can enhance user experience by implementing features like progress indicators, skeleton screens, and handling error states to provide feedback during data fetching, thus improving the perceived responsiveness and interactivity of the application.

Implementing skeleton UX can be challenging as it requires careful design to match the layout of the loading data accurately. It must also be synchronized with the actual content to avoid mismatches and can be complex to implement effectively across different components.

Handling errors and empty states is crucial as it directly impacts user satisfaction and trust. Providing clear messages and recovery options when errors occur or no data is available enhances the user experience by making the application more robust and user-friendly.

To prevent flickering effects in data fetching, developers can introduce a delay before showing progress indicators for fast connections, use skeleton screens to show data layout during loading, and manage asynchronous operations carefully to ensure consistent and smooth updates.

Developers can handle backend errors by categorizing them into user-fixable or server-side issues, providing appropriate feedback and recovery options, and considering automatic retries or redirects depending on the error type to enhance reliability and usability.

An idempotency key is a unique identifier used to prevent duplicate actions in web applications, such as multiple submissions. It ensures that repeated requests for the same action result in only one processed action, which is crucial for operations like payments or bookings.

Developers can manage long-running actions by providing real-time feedback through progress indicators, disabling UI elements to prevent repeated actions, and implementing optimistic updates or timeouts to inform users about the action's progress and maintain a responsive interface.

Toni Petrina
Toni Petrina
21 min
25 Oct, 2021

Comments

Sign in or register to post your comment.

Video Transcription

Available in Español: UX Asincrónico

1. Introduction to Asynchronous UX

Short description:

Today, I'll be talking about Asynchronous UX with React and single-page applications. I'll cover scenarios you'll encounter in your daily job and provide code examples and UX examples. The key takeaway is the importance of building this kind of UX for users and the development cost.

Hi, thank you for joining today's session. My name is Tony and today I'll be talking to you about Asynchronous UX with React and single-page applications. When we say that the web is asynchronous, we are referring to the underlying request-response nature of the web, where a response from the server might take some time to arrive. Traditionally, applications built with server-side rendering in mind were handled by the browser. When we build the same application as a single-page application, we have to build new affordances for the user because the browser can't handle them for us. In today's session, I'm going to go over certain scenarios you will encounter in your daily job and try to address them with code examples and UX examples. At the end of the talk, I hope you'll take away from it that it's very important to build this kind of UX for the users and how much it will cost in terms of development.

2. Exploring Data Fetching and UX

Short description:

Before we begin, let's divide this topic into two areas: read-only data patches and user-initiated actions that change the server state. When navigating the page, fetching data may take some time. To improve the UX, we can add a progress bar or employ skeleton UX. Building more consistent UX can be complex, especially when multiple components have their own proxy indicators. To avoid flickering effects, we can introduce a delay before showing the progress indicator. Let's look at a naive example of code for a page and explore how it can be improved.

Before we begin, I just want to divide this whole topic in two different areas. The first area deals with read-only data patches, and the second area is user-initiated actions that change the state of the server, basically doing form submissions while the queries are page navigations.

Let's talk about queries. So whenever you navigate the page, you might fetch some data. In this naive example, when we navigate to a page, we will fetch the data and then display it to the user. This is a happy scenario where the data arrives somewhat quickly, but depending on the network load, the server load, or the user data, waiting for the data to arrive might take some time. While the user is waiting, we kind of want to inform them that they have to wait in case there are no results. We want to tell them there are no results. If there's an error, we want to tell them that there was an error and what they can do about it.

To improve this UX a bit, we want to add a simple progress bar. This progress is indeterminate because we don't know when it will end, and the user might just want to stick around and wait for the data to arrive. To improve on this very simple progress indicator, we might want to employ skeleton UX. Now skeleton UX looks like the data is going to replace. Basically, this stops flickering effect from happening, because the users will see the outline of the incoming data, and then when the data arrives, it basically just replaces hopefully in place. Unlike progress indicator, skeleton UX is much, much harder to build and can quickly go out of sync with the components they're trying to mimic. So be wary of the complexities involved in building them.

For a bit more complicated page, you can see that when the data is there, you might want to have partial updates with fetching more data. You might want to have different ways of fetching data which might yield different data sizes. So in this case, we can see that sometimes you get little data, sometimes you get no data, sometimes you get an error. And when you have data fetching, you kind of want to reuse this UX. As you can see, building more consistent UX requires some explaining, and you can imagine how much more complicated the code might be. When we build components in our applications, we might want to focus too much on a single component, so each component has its own data fetching and its own proxy indicator. What can happen is that we can quickly end up in a situation where multiple components on the same screen have their own proxy indicators, and then we have this flickering effect as different components have data arriving in a different order. Also, when we have very fast servers, it can be annoying because of the flickering effect because data will arrive very quickly and then the users will see the progress indicator for just a brief time. So to improve that experience, we might want to introduce some kind of delay before showing the progress indicator, so only showing the progress indicator when the data takes a long time to arrive.

Let's take a look at a very naive example of how the code would look for a page. Regardless of whether or not you use React query or Apollo or something similar, your component might look like something like this – you fetch data and you display it inside your UI. Now, can we do better than this? Of course we can, but it will require additional work and it will require a different type of work. So let's take a look at how much more complicated the code can get. On the left side, we can see the naive example from before, and on the right side we'll keep improving it by handling different scenarios that we've shown in the previous demos.

Available in other languages: