loading...
Cover image for How I used React-Loadable to more than halve my React app's load time

How I used React-Loadable to more than halve my React app's load time

rozenmd profile image Max Rozen Updated on ・2 min read

React-Loadable provides you with a component you can use to load a React component later, rather than immediately as you load the React app.

Why would I want to load a component later?

For example, lets say you've inherited a project from another engineer, and they've decided to use moment.js in one of the components.

The output of your webpack build gives you these chunk files, with the main one being 500kB. Of this massive bundle, 65.9kB belongs to the minified + gzipped moment.js library.

Since you're only using the component in a couple of places, it doesn't really make sense to load moment.js immediately as your users load your app. After all, they may not even use the component that uses moment.js!

If instead, you wrapped your component in Loadable, your main bundle would be (roughly) 65.9kB smaller, and only the people that need your component that uses moment.js would download that bundle.

How do I use it?

First, install it:

yarn add react-loadable

or

npm install react-loadable

React-Loadable lets you wrap your massive component like this:

import Loadable from 'react-loadable';
import Loading from './my-loading-component';

const LoadableComponent = Loadable({
  loader: () => import('./my-massive-component'),
  loading: Loading,
});

export default class App extends React.Component {
  render() {
    return <LoadableComponent />;
  }
}

Resulting in a much smaller initial load time for your React app.

<LoadableComponent> doesn't have to be in your App file, it can be anywhere in your component hierarchy.

Halving my React app's load time

Using the above approach was all I needed to shave 200KB from the main bundle of the performance monitoring tool I built (PerfBeacon).

Results:

PerfBeacon results when using react-loadable
Shaving 200KB off PerfBeacon's initial bundle reduced the TTI by more than half

More specifically, I combined react-loadable with react-router-dom to split my bundle by the routes of my web app, resulting in a dozen or so Loadable components like this one:

// pages.js
export default pages = {
  NotFound: Loadable({
    loader: () => import('./NotFound'),
    loading: Loading,
  });
}

While this is great for a start, there's still quite a bit more optimisation work to be done here.

Jamie has a much more in-depth explanation but essentially, any place with tabs, modals, or even low priority content at the bottom of a page can benefit from using react-loadable.

Conclusion

So that's how you can use react-loadable to massively speed up your react app.

Do you manually test your web performance? Do you wish you didn't have to? I'd love to help!

I built PerfBeacon.com to automatically test web performance after each deployment.

Posted on by:

rozenmd profile

Max Rozen

@rozenmd

Frontend Dev at Atlassian. Writes about React & building a SaaS while employed. Building PerfBeacon.com.

Discussion

markdown guide
 

It's 2020! Using react-loadable, the project completely unmaintained for the past 2 years is a very bad decision.
Code splitting is awesome, I totally agree, but there are better ways to use it and better libraries.

I repeat - stop using react-loadable.

If you don't need SSR - use React.lazy, that's all. If you need SSR or looking for more complex solutions - well, there are options.

 
[deleted]
 

James, many people did put their effort. Have tried to fix componentWillMount, tried to fix many other things, ended moving to other projects or forking loadable, cos there were no answers from you, the single maintainer.
Having "other priorities in their life" is not an excuse. If you cannot, or don't want to maintain something - you don't have to. However, please make it clear to the ones who are going to use your creation, and don't stop others from not recomending it due to this condition. Especially if they don't have to use it all.

There is a polite way of interaction with your own library users - open the issues, and add "looking for a maintainer" badge. That would be enough to do anything else you value more.

And thank you for merging some important PRs a few days ago.

[deleted]

You are very kind and focused on yourself only, as you always have been.
In terms of code splitting I did a lot and contributed enough to the other projects code base, theory and practice. Just not in React-Loadable.
Why? Well, every conversation with you ended like that, and I have other priorities in my life.
And if you are allowing you to have them, then allow anyone else to have the same or the different priorities in their life. Please be a bit more self-reflective.

You know, Has anyone told you how stupid you look up on that high horse?.

I know react universal started as a PR to your project back in the day. It defiantly helped us bootstrap the whole chunk-flushing concept to get SSR and code-splitting to play nice. I believe faceyspacey did some collaboration with you a long time ago & for whatever reason. Ended up its own product, following a wave of other projects pulling the SSR feature back into their projects. All of them today are pretty much still based off the flush-chunks/report mechanism.

I know OSS is tedious and projects come and go, new options pop up and so on. React Loadable still works, but I'm sure someone would have taken over maintainership on your behalf. React loadable gets a ton of active downloads and while it still works - somebody should have stepped up to keep it going for the userbase. Especially with the documentation and everything else. Passionate newbie to OSS could have taken over merging pull requests. If nobody came forward then that's kind of crummy on the OSS community. Checking the repo - it's nice to see all the pull requests merged in, but there were like 300 issues or something which has now been disabled.

I can understand your passion. However, Anton does not represent the worst of open-source by any stretch. His contributions have actually made a difference. Solid code, easy to speak to and get support, nice, long term maintenance, works well with others.

Abandoning users isn't a great move either - I always think twice about installing any of your software because its tough to say you're reliable enough - Yeah its not your problem and if im going to depend on code i should be prepared to maintain it. I'm glad it works still but perhaps "request for maintainers" banner could have helped keep it going... I hand off my old projects, but always care for the users.

For someone who has built a career around OSS - you can come across as a bit of a risk.
Users don't really follow the maintainer. Know what's going on in our lives. Reputation ends up being the thing that follows around. While your software is really good, and you're very talented, interactions with the community have been erratic.

I really don't want to get into some pissing contest. Jamie, it's nice to see you active on GitHub again - reach out to the community when you're tired of a project. You could be the gateway for a bright young engineer to get involved in OSS - might even love it as much as you and you'd have been able to get a maintainer, they'd maybe get a new career direction.

[deleted]

I’ve been there as well, more often than not that’s how it can turn out. I’m sorry nobody else stepped up. I really do understand.

It’s good to see you on github. You’ve dedicated a lot to OSS. I’m pretty blunt and direct, but when I hammer the point in - i try to not escalate, if that makes sense? When reading past threads here’s the feeling: “yeah you’re totally right, but how you communicated it made me less inclined to agree. Even though I knew you were completely correct” - maybe I’m out of touch but I feel I haven’t seen you pop up much in a while. If you’re getting back in or just doing some cleanup, you’ve done great work and I just want to see your points of view and ideas be more well received. Maybe I’m off base entirely

 

Just looking to learn here: why is it a very bad decision?

(I wasn't aware of @loadable/component when I posted this, but I've since switched my project over and have found no measurable improvement over react-loadable)

 

Very bad - because it is competely unmaintained. No real answer was given to any issue, no PR has been merged.

Bad - loadable provides only a simples splitting pattern, if you don’t need SSR it’s better just to use React.lazy, it would work just the same.

Other libraries provide a better SSR support, and, for example, able to split not only components.

 

Please change this to use @loadable/components as using an unsupported project is bad practice and leads to security issues.

There are other reasons why loadable is better and you can read those in the react official docs

 
[deleted]
 

Oh so if that package is transferred to a malicious person and you upgrade a patch or minor version, what happens then?

[deleted]

That's good, but sometimes other projects will be transferred to someone that says they will contribute to it and they will plant malicious code in, similar to what happened with event-stream

[deleted]

I'm not dismissing it, React official docs is. I appreciate the hard work that went into it, but as I said some of the pull requests haven't been merged in over 6 months and it seems to have generally less support.

I personally used it in my projects but as we need to ensure we keep only third party libraries that are strictly supported and maintained I can't use or recommend this one anymore and I feel the blog creator should at least provide a few options to the users that might not have the full picture.

Also, don't be rude. I don't know you and your victimism is uncalled for.

 

This is very handy for people! The concept of code splitting and lazy loaded components is 👌👌👌

However react supports lazy loading out of the box and doesn’t need a third party packages to do this, so my advice would be to stick to the official documented route if possible.

reactjs.org/docs/code-splitting.html

 

However Lazy covers only component level splitting.
"Other libraries" have already implemented library-level splitting in form of renderProps or resource level splitting in form of hooks, which let you reduce you bundle size even more.

 

Is lazy loading a component on the page better than having it just be in the initial bundle? For example by using next/dynamic when you have a huge component on the home page is it better to let it be bundled or does making it dynamic have any benefits,does it defer its loading? Could never understand this 😅