---
# System prepended metadata

title: Lazy loading in React 18
tags: [self-taught, published, blog]

---

# Lazy loading in React 18

### I. What is lazy loading

> Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.
Lazy loading can occur on different moments in the application, but it typically happens on some user interactions such as scrolling and navigation.
> <div style="font-size: 12px"><u>src</u>: https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading</div>

So basically, it's a practice of delaying load or initialization of resources or objects until they’re ready to be load or until users need them. 
By this, we can improve performance and save system resources. 

*<u>Ex</u>*: when you fetching data from API, it takes time, and we usually show a loading text or spiner to let users know data is loading.

### II. Old method

What we used to do to display the loading sign while waiting for API to fetch is:
- creating a loading state (false, initially)
- then when we fetch API, loading state is updated to `true`
- when the fetch is done, loading state was updated to false
- we also have an `if` statement on render to output the loading sign when it's state is true, otherwise, render the fetched content

```javascript=
import './App.css';
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { solid } from '@fortawesome/fontawesome-svg-core/import.macro';
import BerlinTemp from "./WeatherTag";
import NYTemp from "./WeatherTag2";
import SFTemp from "./WeatherTag3";

function App() {

  return (
      <div
        style={{
          width: "100%",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          padding: "40px 0"
        }}  
      >
        <h2>
          <span>How's the temperature today ?</span>
        </h2>
        <BerlinTemp />
        <NYTemp/>
        <SFTemp/>
      </div>
  );
}

export default App;
```

What is painful about this is that, anywhere you want a loading sign, you'll need a state to control the loading status. So i have a loading state for each `<BerlinTemp/>`, `<NYTemp/>`, `<SFTemp/>` component.
It is not that big of a deal, but wouldn't it be nice if we don't have to to that.

### III. With React 18

"Suspense" has been around for several versions as an experimental feature. React 18.0.0 was out on March 29, 2022 making it an official feature together with some other updates.

The above code will be re-write as below:
```javascript=
import './App.css';
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { solid } from '@fortawesome/fontawesome-svg-core/import.macro';
const NYTemp = React.lazy(() => import ('./WeatherTag2'));
const BerlinTemp = React.lazy(() => import ('./WeatherTag'));
const SFTemp = React.lazy(() => import ('./WeatherTag3'));

function App() {

  return (
      <div
        style={{
          width: "100%",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          padding: "40px 0"
        }}  
      >
        <h2>
          <span>How's the temperature today ?</span>
        </h2>
        <React.Suspense fallback={<FontAwesomeIcon icon={solid('rotate')} spin/>}>
          <BerlinTemp />
          <NYTemp/>
          <SFTemp/>
        </React.Suspense>
      </div>
  );
}

export default App;
```

- We no longer need loading state in each component
- Instead, wrap the components with `Suspense` which takes a required `fallback` props to display the loading sign when components are fetching data.
- And, the components also need to be imported with `lazy()` to make it work.

**==> We have the same result as the old method.**
![](https://i.imgur.com/3DTiM3E.gif)

Another interesting thing is that, we can add suspense inside a nother suspense, and it will delay the display of 2nd suspense until the first one was rendered.

```javascript=
...
<React.Suspense fallback={<FontAwesomeIcon icon={solid('rotate')} spin/>}>
    <BerlinTemp />
          {/* <NYTemp/>
          <SFTemp/> */}
    <React.Suspense fallback={<FontAwesomeIcon icon={solid('rotate')} spin/>}>
        <NYTemp/>
        <React.Suspense fallback={<FontAwesomeIcon icon={solid('rotate')} spin/>}>
            <SFTemp/>
        </React.Suspense>
    </React.Suspense>
</React.Suspense>
...
```

--> As you can see, `<BerlinTemp/>` component is loaded first, then `<NYTemp/>`, and finally `<SFTemp/>`
![](https://i.imgur.com/zB5zG3Y.gif)

### IV. Conclusion
If you're using React 18, give it a try.
I bet you'll like it.
See you again with another cool updates from React.

<small>
    Published date: 2022-05-22 <br/>
    Also published <a href="https://medium.com/goalist-blog/lazy-loading-in-react-18-c4b4a86a9441">here</a>.
</small>