React - Load API content as elements become visible to users

Arnaud Lachaume
Arnaud LachaumeLink to author's LinkedIn profile
June 8, 2021
icon timer

Is your SPA making too many requests to your backend? Here is a quick and easy way to load API content more progressively as items become visible. Also we will show you how to display graceful loaders that actually represent your content while elements are loading.

Table of Content

TL;DR; You can reduce the number of queries you make on listing pages by loading content as it gets displayed. Use react-intersection-observer to detect when an element becomes visible and react-content-loader to display a contentful placeholder loader.

You have a developed your backend API and built your React SPA but you find that some pages actually make a lot of requests (either large or lots) to your backend and have become kind of sluggish. Well good news everyone, you can improve that.

Let's consider a typical layout for a "listing" page. What matters here is not the design but the architecture of the page. You have a list of items and then for each item a list of children. All of these must be dynamically loaded from your API.

A standard listing page layout

What are the traditional approaches?

  1. One big query: You make one fat API query to your backend to load the items and their children (e.g. comments). It works, is perfectly valid for a small number of items but is merely scalable if you expect a high number of children. The biggest problem is being in control of the pagination for the children, which is merely possible when you include children in the parent query. Even with GraphQL, which allows you to paginate children, you would redo the parent query for each new page - this is not optimal.
  2. One query per item: You load items - or item IDs - using a listing query then for each item you load the item body (if not loaded as part of the first query) and the children. This approach is scalable and gives you better control over pagination.

Option 2 is more fluid in terms of architecture. The problem is you'll end up doing quite a lot of queries on page load depending on the number of items you wish to display on the initial page load. Loading 100 items means you'll end up doing N x 100 queries on your API, where N is the number of correlated resources you need to load for each item.

Considering most of the items will be below the fold, it seems like a huge waste of resources to load everything on page load. A better approach would be to load items as they become visible to users.

Let's do just that.

The useInView hook to the rescue

The react-intersection-observer library provides a hook detecting when an element becomes visible to users.

It has plenty of configuration options - such as configuring a percentage threshold of object height for when to trigger the inView event - but we'll go with the most basic implementation here.

Add react-intersection-observer to your project:

Now you can use the inView hook on your page items to conditionally load related children:

That's it. You've just saved your backend hundreds of queries potentially.

The useInView hook will guarantee that your API queries are only executed if your element actually becomes visible to the user.

Now we've considerably increased the number of components that will be in a loading state as the user scrolls your page. Therefore let's make that loading state nice and contentful.

Contentful placeholder loader

The react-content-loader loader library allows you to define pulsing SVG objects to be used as a placeholder while your content is loading.

I find this approach nicer than the traditional spinners as it gives your users an indication of what to expect in terms of layout once your content is loaded.

Here is an example of a comment placeholder loader:

Example of comment loader

The nicest thing about this library is that the author actually developed a site to help you design these SVG loaders. Just go to and get fancy!

Now let's incorporate that placeholder into our component.

First install the library in your project:

Then design your component on and add it to your project:

Finally conditionally display your loader in your comment feed component:

That's it!

Your comment feeds now load dynamically as users scroll your page and a nice placeholder loader lets them know it's coming!

Sign-up and accelerate your engineering organization today !

About us

Keypup's SaaS solution allows engineering teams and all software development stakeholders to gain a better understanding of their engineering efforts by combining real-time insights from their development and project management platforms. The solution integrates multiple data sources into a unified database along with a user-friendly dashboard and insights builder interface. Keypup users can customize tried-and-true templates or create their own reports, insights and dashboards to get a full picture of their development operations at a glance, tailored to their specific needs.


Code snippets hosted with ❤ by GitHub