Tutorial

How To use Skeleton Screens in React and React Native

Updated on June 24, 2021
author

Chris Dolphin

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.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Chris Dolphin

author

Still looking for an answer?

Ask a questionSearch for more help

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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.