Declarative Resource Loading with React
Tags: react, suspense, webdev, experimental
Published: 2019-04-15 04:38:35

---
title: Declarative Resource Loading with React
published: true
description: A written version of my talk at San Diego ReactJS meetup
tags: React, Suspense, webdev, experimental
cover_image: https://images.unsplash.com/photo-1417309807426-472e833fa5d0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80 
---
^(photo by @alexjones on unsplash.com)


# Loading Stuff is Hard 

how many of you write the word _isLoading_ 10x a day? Often times we want to make our application responsive even in slow connections, so we have loading indicators to give the user feedback that the app is working. If you think about your application, a lot of time and energy is focused on coordinating when stuff comes in, when it comes out, and what to show the user. This is any resource our browser uses, even resources that we don't fetch explicitly like images, fonts, code, etc. impact our time to interactive and UX. In this post, we'll take a look at a few approaches to load resources in our apps and how this is going to play in the near future.


# Code Splitting

Code splitting is when you only send the code that’s required to load the page you are visiting, and then the rest of the code is sent to the client as the user navigates. Although there are a lot of other ways of achieving this, React has a couple of APIs which help us split the bundle into chunks of code that are grouped in the most efficient way to reduce their file size. The first API we need in order to split our application is called lazy, it is super simple, it takes a function that returns a dynamic import and then that’s a drop-in replacement for your component.

![lazy example](https://thepracticaldev.s3.amazonaws.com/i/ewbka5r18kuhg1mp45jt.png)

the other API is called Suspense. Suspense helps us determine if the resources we are trying to call are available to use and displays an alternative loading state while the resource becomes available. In other words, Suspense is a declarative loading state API.

# Data Fetching

Look at the following example of a traditional class-based data fetching component:

![class exampled](https://thepracticaldev.s3.amazonaws.com/i/6d4ua56fv60k7ijplo7i.png)

it initializes the state on the constructor, fetches the data on-mount, and when it renders it evaluates if there is data to present or if it's ok to display a loader fallback instead. You must be thinking, of course using hooks would make it better right?

![hooks example](https://thepracticaldev.s3.amazonaws.com/i/54qlum4imud6nyejqiem.png)

With Hooks, you fetch data using effects and imperatively checking the loading state to display a loader until the resource becomes available. We reduced some boilerplate code and made it cleaner, but it is still the same process, it still imperatively decides whether to present a loader or content.


Until now, we have only been able to use Suspense to load dynamic code with lazy, but in reality, we can use it for other types of resources too. You can suspend any element in your component hierarchy, if the calling resource can’t suspend the rendering of that subtree and provide a fallback it will look up the tree until it finds one that can or it errors out, it works exactly like an error boundary.

![suspense example](https://thepracticaldev.s3.amazonaws.com/i/mqzprzqe9fz85eg4wvvw.png)

Suspense allows async resources to behave as if they had sync access. We don't even have a loader on our fetching component now, we just let React know that the resource ain't ready yet and Suspense will provide a fallback somewhere along the tree to wait for our resources to be ready to render.


Not only does Suspense improve our DX by reducing our lines of code exponentially but it also allows for a smoother transition between loading states like when your app goes from lazy loading the code to fetching data.


# Other Resources

Another great example is images, sometimes our pages render and some images are missing, the requests for those resources can be on the heavier side. Let's do our new trick and load an image using Suspense.

![suspense image](https://thepracticaldev.s3.amazonaws.com/i/0kvgygcg6a5dpaia1is7.png)

Of course, you don't have to do this yourself, [the-platform](https://github.com/palmerhq/the-platform) is a nifty library that has your back with wrapped components for images and other resources that are Suspense-ready.

![suspense with thumbnail](https://thepracticaldev.s3.amazonaws.com/i/h17zoyqkrhvu0waolk6z.png)

As a fallback, you could have a regular `<img/>` tag with a lower-res thumbnail instead of a spinner and it will provide a smooth transition between the thumbnail and the full-size image.


# Strict Mode

So now we have a few resources loading and our application might start to feel slow if we keep that loader going, we need to decide how much are we willing to wait for each resource. I definitely need to retrieve the code and data first, but I could get away with showing a low-res thumbnail for a few seconds longer in order to deliver an almost complete UI. Suspense provides us with a second prop called `maxDuration` and this prop allows us to specify in milis how much should it wait till it provides a fallback or content. `maxDuration` will only work when certain conditions are met, this is where things get a little tricky. 

In order for React to appropriately evaluate what is going on, there should be no deprecated APIs in the suspended tree. to help us identify possible issues React exposes a tag called `StrictMode`. Strict mode is a stable API and you can use it right now in production, nothing will break, however, if there are any deprecated APIs used within its children you will be getting errors on your browser's console.


# Concurrent Rendering

If you wrapped your app in strict-mode and your console is still clear, congratulations! You are now able to activate concurrent mode and start taking advantage of `maxDuration`. But what exactly is _Concurrent mode_? In the words of Dan Abramov:

> Concurrent Mode lets React apps be more responsive by rendering component trees without blocking the main thread. It is opt-in and allows React to interrupt a long-running render (for example, rendering a new feed story) to handle a high-priority event (for example, text input or hover). Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections.

There are 2 ways of enabling concurrent mode in your application, again, these features are experimental and expected to ship sometime around Q2 2019. React-dom exposes a function called `createRoot` (currently _unstable_createRoot_), it receives the dom reference to the element where the app will be rendered, you can chain a `render` method with the app instance.

![create root](https://thepracticaldev.s3.amazonaws.com/i/yfxcv4essjs8cr1ntjgi.png)

As an opt-in feature, React exposes a tag called `ConcurrentMode` which you can use to wrap subsections of your app to enable concurrent rendering only in their subtrees. 


For a demo visit https://sdjs-demo.jdmg94.now.sh
For the full source visit:

{% github https://github.com/jdmg94/sdjs-suspense-demo %}