What is Skeleton Loading and how to implement it in React
Tags: react, webdev, tutorial, todayilearned
Published: 2021-04-14 12:25:09

## Background

Last week, I saw an interesting thread discussion about how to reduce the [Largest Contentful Paint (LCP)](https://web.dev/lcp/) time that is caused by *a component that takes a long time to load*.

- In 2020, **LCP** was 1 of the 3 metrics of the [Core Web Vitals](https://web.dev/vitals/#core-web-vitals) declared by Google to be crucial for delivering a great user experience on the web. The Core Web Vitals score affects how your webpage is reflected in *search rankings,* and is a *Search Engine Optimization* (SEO) concept that developers should be aware about once we start considering about the *business value* of a site.
- You can also use the [Lighthouse](https://developers.google.com/web/tools/lighthouse/) report service offered by Google, to identify *quality of your webpage* based on various categories. LCP is considered a facet under *Performance*.

The initial suggestion by the thread starter was to:

1. use a placeholder image until the slow component has finished loading
2. and then swap it out.

Another user then pointed out that this is in fact an implementation of **Skeleton Loading** - a phrase that *I have not heard before* 🧠

Hence, I decided to write this article to share my findings on what it is 💪 I'll also share the resources at the end if you are keen on reading the articles yourself.

---

## Rethink the concept of Loading 🔃

Before stumbling upon that thread, I always had the preconception of just adding a Loading Spinner if any component requires a **loading state** due to slow operations such as *fetching of data* or *updating the database*.

However, when I read up online on how Skeleton Loading is usually implemented, it is actually *this specific component* that we sometimes see on social media, newspaper and community platforms 👇

![https://raw.githubusercontent.com/alexZajac/react-native-skeleton-content/master/demos/main.gif](https://miro.medium.com/max/640/0*4SHQvj9V-jfMJDSO.gif)

*Example from [UX Collective](https://uxdesign.cc/what-you-should-know-about-skeleton-screens-a820c45a571a)*

That kind of explains why this component is called the **Skeleton Loading** component since it is literally this:

🦴  ➡️  🍖  ➡️  🍗

1. The component is initially a *skeleton* 🦴
    - to indicate to the user a **rough layout of what they are going to see**
2. The skeleton component slowly gets *loaded with more meat* 🍖
    - where more useful content is rendered and shown to the user.
    - to give the user a sense of progress in waiting for the component to load
3. Once the component is fully loaded, the user should still *hold the drumstick by the bone* 🍗
    - **The layout of the component relative to its parent should remain the same**
    - so that the user's experience feels consistent and coherent even when all the component has finished loading and renders entirely what it was intended to show

Afterwards, I looked up on *how it is usually implemented*.

## How Skeleton Loading is usually implemented

There were 2 common packages that were brought up

1.  `react-loading-skeleton`
2.  `@material-ui/core`

On their sites, examples of *how to use* the Skeleton component from the respective packages were included. In both examples, the use of an `if else` conditional rendering statement in the component directly was necessary in the component render method.

---

### react-loading-skeleton library

Example from `react-loading-skeleton` 

```
<div style={{ fontSize: 20, lineHeight: 2 }}>
  <h1>{this.props.title || <Skeleton />}</h1>
  {this.props.body || <Skeleton count={10} />}
</div>
```

Despite having **2.1k** ⭐ on its [Github repository](https://github.com/dvtng/react-loading-skeleton), It was a little hard to find from their documentation on how specific variants of their component look like. However, I noticed that they do have a storybook (a popular library for showcasing frontend components). If you're keen, you can clone it and start it locally as well to see what they offer. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nsceal3fazasw376htc.png)
 

---

### material-ui library

Example from `@material-ui/core`

```
{item ? (
  <img style={{ width: 210, height: 118 }} alt={item.title} src={item.src} />
) : (
  <Skeleton variant="rect" width={210} height={118} />
)}
```

For the types of Skeleton components that they offer, you can visit [their site](https://material-ui.com/components/skeleton/) for viewing directly, their documentation is quite detailed. The [Github repository for this library](https://github.com/mui-org/material-ui) has **67.6k** ⭐.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndaby539zra7gfkirad9.png)

*Screenshot of Material UI's documentation page on Skeleton*
 

Material UI also included [this article by Luke Wroblewski](https://www.lukew.com/ff/entry.asp?1797) (*currently Product Director at Google*) on why the loading spinner should be avoided.

## Food for thought on the package 🍎

Both packages seem pretty good if we require a Skeleton component. The Material-UI library also comes with a lot more of other components, styles and features rather than just the Skeleton. However, if we don't use them then it could take up more *file size* than necessary when we build and bundle our app. You will have to weigh the pros and cons when deciding which package to use. 

## Food for thought on the code example 🍏

Rather than which package to use - I was actually more intrigued by the coding style of both examples given to use the Skeleton component. Between the two coding styles on **how to use** the Skeleton component,

- I would prefer the use of `||` whenever possible
- the ternary operators `() ? () : ()` are generally harder to read for someone who is not familiar with the component.
- The `||` operator also enforces you to write your logic simpler.

But *why do we have to write it this way* 🤔

1. *is there really no other way* to add Skeleton component logic without an `if else` conditional rendering statement in it?
2. What if there are many components that requires a Skeleton - does that mean I have to write *similar logic repeated over and over again* in the render method?

---

An idea then came to my mind 💡 - why not implement the Skeleton logic with *React Hooks?* ✨

> 💡 So, I'll try to do that and share the results of my attempt **in the next article**, look forward to that!

Meanwhile, below are the resources that I read through before writing this article, they were very insightful and you can have a look at them too!

---

## Resources

Resources on **what** is React Skeleton and **why** use it:

- Article on *Designing for Appearance of Speed*: [https://juneuprising.medium.com/designing-for-the-appearance-of-speed-aaabc7f568c2](https://juneuprising.medium.com/designing-for-the-appearance-of-speed-aaabc7f568c2)
- Article on *a research conducted on React skeleton vs Loading Spinner*: [https://uxdesign.cc/what-you-should-know-about-skeleton-screens-a820c45a571a](https://uxdesign.cc/what-you-should-know-about-skeleton-screens-a820c45a571a)

---

Resources on **how** React Skeleton can be implemented:

- Create React Content Loader - Tool to easily create animated skeleton-screen components: [https://skeletonreact.com/](https://skeletonreact.com/)
- Article on how to implement React Skeleton with the `react-loading-skeleton` package: [https://betterprogramming.pub/the-what-why-and-how-of-using-a-skeleton-loading-screen-e68809d7f702](https://betterprogramming.pub/the-what-why-and-how-of-using-a-skeleton-loading-screen-e68809d7f702)
- Material UI React Skeleton: [https://material-ui.com/components/skeleton/](https://material-ui.com/components/skeleton/)

---

## Conclusion

Thank you very much for reading this article! 🌟

Leave a **heart** 💌 and a **unicorn** 🦄 if you like this article!

Please give me some **feedback** below 👇 I would love to hear from you about how you feel after reading this article or if you have any recommendations for me to learn how to write custom hooks!