// Tutorial //

How To use Skeleton Screens in React and React Native

Published on October 31, 2018 · Updated on June 23, 2021
Default avatar
By Chris Dolphin
Developer and author at DigitalOcean.
How To use Skeleton Screens in React and React Native

Introduction

A skeleton screen is a term coined by Luke Wroblewski for describing a user experience pattern for displaying neutral elements while gradually loading content into a container.

This pattern focuses on improving the perceived performance. When compared against a blank screen or a traditional spinner, skeleton screens are seen as shorter in duration.

Motion and linear-gradient animations are perceived to be quicker than motionless or pulsating loading animations. For images, using their dominant colors with placeholder elements can also be effective.

In this article, you will be presented with several solutions for implementing skeleton screens in your React and React Native applications.

Using Skeleton Screens in React

In React, it is possible to achieve a skeleton screen effect with componentDidMount and a linear gradient.

However, instead of implementing your own solution, you may want to consider some of the more robust community options crafted to encourage scalability: react-content-loader, react-skeletor, and react-loading-skeleton.

react-content-loader comes loaded with presets for lists, code, and Facebook-styled and Instagram-styled loading cards. It also allows for custom SVG, elements, and color.

Here is an example of react-content-loader:

import ContentLoader, { Facebook } from 'react-content-loader';

const MyFacebookLoader = () => <Facebook />

const MyLoader = () => (
  <ContentLoader>
    {/* Pure SVG */}
    <rect x="0" y="0" rx="5" ry="5" width="70" height="70" />
    <rect x="80" y="17" rx="4" ry="4" width="300" height="13" />
    <rect x="80" y="40" rx="3" ry="3" width="250" height="10" />
  </ContentLoader>
)

Alternatively, react-placeholder and SVG-Skeleton are two other popular out-of-the-box solutions that provide placeholder components and styling.

react-skeletor allows for full customization by providing higher-order components with direct connections to load conditionals.

Here is an example of react-skeletor:

import { createSkeletonProvider, createSkeletonElement } from '@trainline/react-skeletor';

const H1 = createSkeletonElement('h1');
const H2 = createSkeletonElement('h2');

const NameCard = ({ firstName, lastName }) => (
  <div>
    <H1 style={style}>{ firstName }</H1>
    <H2 style={style}>{ lastName }</H2>
  </div>
)

const UserDetailPage = ({ user }) => (
  <div>
    ...
    <NameCard user={user} />
    ...
  </div>
)

export default createSkeletonProvider(
  // Dummy data with a similar shape to the component's data.
  {
    user: {
      firstName: '_____',
      lastName: '_____'
    }
  },

  // Predicate that returns true if the component is in a loading state.
  ({ user }) => user === undefined,

  // Define the placeholder styling for the children elements.
  () => ({
    color: 'grey',
    backgroundColor: 'grey'
  })
)(UserDetailPage)

This blog post goes into further detail on the benefits of using react-skeletor.

react-loading-skeleton automatically creates skeleton screens from the styles themselves, eliminating the need to create dedicated skeleton screen components altogether.

Here is an example of react-loading-skeleton:

import Skeleton from 'react-loading-skeleton';

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

That concludes using skeleton screens in React.

Using Skeleton Screens in React Native

React Native applications can consider two community options: react-native-svg-animated-linear-gradient and react-native-shimmer.

react-native-svg-animated-linear-gradient can created an animated linear gradient effect.

Here is an example of react-native-svg-animated-linear-gradient:

import SvgAnimatedLinearGradient from 'react-native-svg-animated-linear-gradient';

// Instagram style.
<SvgAnimatedLinearGradient height={300}>
    <Circle cx="30" cy="30" r="30"/>
    <Rect x="75" y="13" rx="4" ry="4" width="100" height="13"/>
    <Rect x="75" y="37" rx="4" ry="4" width="50" height="8"/>
    <Rect x="0" y="70" rx="5" ry="5" width="400" height="200"/>
</SvgAnimatedLinearGradient>

react-native-shimmer is a React Native implementation of Facebook’s Shimmer implemented in iOS and Android.

Here is an example of react-native-shimmer:

import Shimmer from 'react-native-shimmer';

<Shimmer>
  <Text>Loading...</Text>
</Shimmer>

That concludes using skeleton screens in React Native.

Exploring Alternatives

Outside React, the JavaScript community has solved this problem as well. Placeload.js is a popular solution. jquery.skeleton.loader is a jQuery plugin.

And Semantic UI has its own built-in Placeholder element.

Using Images and Dominant Color

Instead of creating a shimmer effect with gradients, an image’s dominant color can give guidance and context to the user before the content is loaded.

A few resources on extracting the primary colors from an image: color-thief, node-vibrant, and color-loader.

Conclusion

In this article, you were presented with several solutions for implementing skeleton screens in your React and React Native applications.

This presentation by Luke Wroblewski introduces skeleton screens.

These articles go into detail about using skeleton screens: Everything you need to know about skeleton screens and Stop Using Loading Spinner, There’s Something Better.

Serverside Rendering (SSR) is a big part of managing users’ page load experience. Relevant skeleton screens should be included in the “App Shell” and initial page load. Addy Osmani covers how this works with React.

Accessibility should be a consideration as screen-readers and assistive software can become tripped-up and create confusing experiences when it comes to extra page elements like skeleton screens. Ray Roman suggests using ARIA labeling, like aria-disabled={true} or aria-label="loading", to help ignore these elements.

Before implementing skeleton screens, you may wish to consider the counter-arguments in A Bone to Pick with Skeleton Screens.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
Leave a comment

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!