Open In App

What are the differences between React.lazy and @loadable/components ?

Last Updated : 03 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Before discussing the difference between React.lazy and @loadable/components, let’s talk about what are they and why we need them. Both React.lazy and @loadable/components are mainly being used for the process of Code-Splitting

Code-Splitting: Code-Splitting is an optimization technique supported by bundlers like Webpack, Rollup, and Browserify (via factor-bundle) which allows us to split our code into multiple bundles or chunks that can be dynamically loaded at runtime on-demand or in parallel. 

It’s an efficient way to reduce your application bundle size because we are just “lazy-loading” the things that are currently needed by the user.

Although we have not reduced the overall amount of code in our app this way, we have avoided loading the code that the user may never need. Which in turn reduces the amount of code needed during the initial load and improves the overall loading time of your application dramatically.

React implement Code-Splitting: React supports code splitting out of the box with React.lazy since version 16.6.0.

It has been a common practice since then,  to split our components in a React application. However only splitting is not enough, it must be able to wait for the component to be loaded (while showing a fallback UI during loading) and also handle any potential errors.

That’s why we need to use Suspense and Error Boundaries with it.

Javascript




import React, { Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';
  
const SomeComponent = React.lazy(() => import('./SomeComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
  
const MyComponent = () => (
    <div>
        <MyErrorBoundary>
            <Suspense fallback={<div>Loading...</div>}>
                <section>
                    <SomeComponent />
                    <AnotherComponent />
                </section>
            </Suspense>
        </MyErrorBoundary>
    </div>
);


As we can see from the above example, React.lazy takes a function that is calling a dynamic import() and returns a Promise which resolves to a module with a default export containing a React component. The lazy component is then 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.  An Error Boundary is also used to handle any errors that may be caused due to a network issue or similar reason. 

@loadable/component: Although React.lazy with Suspense is the recommended solution for Code Splitting, it has some limitations.  React.lazy and Suspense are not yet available for Server-Side Rendering. So if you want to do Code-Splitting in a server-rendered app, that’s when @loadable/component comes into play.

Javascript




import loadable from '@loadable/component'
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        <div>
            <OtherComponent />
        </div>
    )
}


So what are some major differences between them? 

  SSR Suspense Library splitting Full dynamic import
React.lazy
@loadbale/component

SSR: @loadable/component provides a complete solution to make Server Side Rendering possible, whereas React.lazy is not an option when it comes to Server Side Rendering. Because Suspense is not available in Server-Side and React.lazy can only work with Suspense.

Suspense: Although Suspense is supported by both by @loadable/component and React.lazy, the difference between them is @loadable/component can also be used without Suspense.

Javascript




const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        <div>
            <OtherComponent fallback=
                  {<div>Loading...</div>} />
        </div>
    )
}


Library splitting: @loadable/component supports library splitting using render props, which is not possible with React.lazy.

Javascript




import loadable from '@loadable/component'
const Moment = loadable.lib(() => import('moment'))
function FromNow({ date }) {
    return (
        <div>
            <Moment fallback={date.toLocaleDateString()}>
                {({ default: moment }) => 
                    moment(date).fromNow()}
            </Moment>
        </div>
    )
}


Full dynamic import: Webpack supports full dynamic imports or aggressive code splitting. You can use them to create a reusable Loadable Component by passing a dynamic value to the dynamic import() function.

Javascript




import loadable from '@loadable/component'
const AsyncPage = loadable(props => 
    import(`./${props.page}`))
function MyComponent() {
  return (
    <div>
      <AsyncPage page="Home" />
      <AsyncPage page="Contact" />
    </div>
  )
}




Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads