question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

import() is great for code splitting, but it’s not enough to use in your app on it’s own.

React Loadable provides the rest for any React app:

But the biggest problem is with server-side rendering.

When you use an app with nested asynchronously loaded components, it creates this waterfall effect. One component loads to render it’s children where one of the children loads another component which loads another component and so on.

This forces you to be annoyingly careful with which component you allow to load async.

React Loadable manages to use server-side rendering in order to avoid this waterfall. It preloads all of your components server-side and as it renders them it makes sure to send down the relevant <script> and <link> tags.

I know that Create React App doesn’t do any kind of server-side rendering (yet?), but React Loadable is a really great default for the ecosystem but I would like to see what it would look like if we set up a client-side portion for CRA users.

Right now the way I have people set it up looks like this:

// src/entry.js
import React from 'react';
import ReactDOM from 'react-dom';
import Loadable from 'react-loadable';
import App from './components/App';

window.main = () => {
  Loadable.preloadReady().then(() => {
    ReactDOM.hydrate(<App/>, document.getElementById('app'));
  });
};
    <script src="/dist/main.js"></script>
    ...
    <script>window.main();</script>
  </body>
</html>

That way we can trigger our code to run after all the other necessary bundles are in place, which makes for a seamless transition when doing server-side rendering.

Using React Loadable like this allows you to place hundreds of dynamically loaded components all over your app without slowing down the startup experience with loading screens and speeding it up by not needing to load nearly as much code.

Is there something that we can put in Create React App that makes it easier to setup React Loadable or similar tools?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:11
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
gaearoncommented, Nov 5, 2017

I wonder how often people add SSR to CRA projects, as opposed to starting from a SSR-specific boilerplate or something like Next.js. Not sure how we can get data on that.

4reactions
andreiducacommented, Dec 18, 2017

React Loadable can be used with CRA with named imports:

import Loadable from 'react-loadable';
const Landing = Loadable({
    loader: () => import(/* webpackChunkName: "LandingChunk"*/ './pages/Landing'), // <-- this will tell webpack to generate named bundles
    loading: () => null,
    modules: ['LandingChunk'], // <-- this is what we'll use to map components to js bundles
});

This will produce the following output in the manifest file asset-manifest.json:

{
  "LandingChunk.js": "static/js/LandingChunk.c89b1c6b.chunk.js",
  "LandingChunk.js.map": "static/js/LandingChunk.c89b1c6b.chunk.js.map",
  "main.js": "static/js/main.b164574b.js",
  "main.js.map": "static/js/main.b164574b.js.map"
}

and, on the server, the Loadable.Capture will get the following:

const modules = [];
const html = ReactDOMServer.renderToString(
    <Loadable.Capture report={moduleName => modules.push(moduleName)}>
        <App />
    </Loadable.Capture>
);

console.log(modules);
/*
[ 'LandingChunk' ]
*/

From here, it’s just a matter of mapping this to the entries in the manifest file:

import manifest from '../../build/asset-manifest.json';

const extractAssets = (manifest, chunks) => Object.keys(manifest)
    .filter(c => chunks.indexOf(c.replace('.js', '')) > -1)
    .map(a => manifest[a]);

// ...

console.log(extractAssets(manifest, modules));
/*
[ 'static/js/LandingChunk.c89b1c6b.chunk.js' ]
*/

Everything else works as described in the docs: https://github.com/thejameskyle/react-loadable#preloading-all-your-loadable-components-on-the-server, BUT without the need of the extra webpack plugin.

Read more comments on GitHub >

github_iconTop Results From Across the Web

jamiebuilds/react-loadable: A higher order component for ...
React Loadable is a small library that makes component-centric code splitting incredibly easy in React. Loadable is a higher-order component (a function that ......
Read more >
Loadable Components - React code splitting
React code splitting made easy. What is it? A React code splitting library; Not an alternative to React.lazy; A solution recommended by React...
Read more >
Introducing React Loadable – @thejameskyle
React Loadable is a small library I wrote to make component-centric code splitting easier in React. Loadable is a higher-order component (a function...
Read more >
Code Splitting in React Using React Loadable - DigitalOcean
React Loadable is a library by @jamiebuilds that makes it easy to implement code splitting in React and that embraces React's component ...
Read more >
Introducing React Loadable - by Jamie Kyle - Medium
Component-centric code splitting and loading in React. “Introducing React Loadable” is published by Jamie Kyle.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found