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.
Comments