Bundling and Code-splitting

Bundling

Bundling is the process of following imported files and merging them into a single file: a "bundle". This bundle can then be included on a webpage to load an entire app at once.

Code Splitting

To avoid winding up with a large bundle, it’s good to get ahead of the problem and start “splitting” your bundle. Code-Splitting is a feature supported by bundlers like Webpack, Rollup and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime.
Code-splitting your app can help you “lazy-load” just the things that are currently needed by the user, which can dramatically improve the performance of your app.

instead of


    import { add } from './math';
    console.log(add(16, 26));
        

use


    import("./math").then(math => {
        console.log(math.add(16, 26));
    });
        

Lazy Loading

Automatically load the bundle containing the component when this component is first rendered.

// React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.
// The lazy component should then be rendered inside a Suspense component, which allows us to show some fallback content (such as a loading indicator) while we’re waiting for the lazy component to load.
// You can even wrap multiple lazy components with a single Suspense component. // If the other module fails to load (for example, due to network failure), it will trigger an error. You can handle these errors to show a nice user experience and manage recovery with Error Boundaries.

    import React, { Suspense } from 'react';
    import MyErrorBoundary from './MyErrorBoundary';
    const OtherComponent = React.lazy(() => import('./OtherComponent'));

    function MyComponent() {
        return (
            <div>
                <MyErrorBoundary><Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense></MyErrorBoundary>
            </div>
        );
    }
        
// more on Error Boundaries here.

Route-based code splitting


    import React, { Suspense, lazy } from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

    const Home = lazy(() => import('./routes/Home'));
    const About = lazy(() => import('./routes/About'));

    const App = () => (
        <Router>
            <Suspense fallback={<div>Loading...</div>}>
                <Switch><Route exact path="/" component={Home}/><Route path="/about" component={About}/></Switch>
            </Suspense>
        </Router>
    );