Lazy Loading

Lazy Loading

One of the main problems with shipping too much JavaScript is that it can slow down page load times. JavaScript files are typically larger than other types of web assets, such as HTML and CSS, and require more processing time to execute. This can lead to longer page load times, especially on slower internet connections or older devices.

In this example, the large.js file is loaded asynchronously using the async attribute. This means that it will be downloaded in parallel with other resources on the page, which can help improve page load times.

<!DOCTYPE html>
<html>
  <head>
    <title>My Website</title>
    <script async src="https://example.com/large.js"></script>
  </head>
  <body>
    <!-- Page content goes here -->
  </body>
</html>

For example, consider the following code snippet that uses code splitting to load only the JavaScript that is needed for a particular page:

import("./large.js").then((module) => {
  // Use module here
});

In this example, the import function is used to asynchronously load the large.js file only when it is needed. This can help reduce page load times and data usage by only loading the necessary code.

Another approach is to use lazy loading to defer the loading of non-critical JavaScript until after the page has loaded. This can help reduce page load times and data usage by loading non-critical code only when it is needed.

<!DOCTYPE html>
<html>
  <head>
    <title>My Website</title>
  </head>
  <body>
    <!-- Page content goes here -->
    <button id="load-more">Load more content</button>
    <script>
      document.getElementById("load-more").addEventListener("click", () => {
        import("./non-critical.js").then((module) => {
          // Use module here
        });
      });
    </script>
  </body>
</html>

In this example, the import function is used to asynchronously load the non-critical.js file only when the “Load more content” button is clicked. This can help reduce page load times and data usage by loading non-critical code only when it is needed.

import Sidebar from "./Sidebar"; // 22MB to import

const MyComponent = ({ initialSidebarState }) => {
  const [showSidebar, setShowSidebar] = useState(initialSidebarState);

  return (
    <div>
      <button onClick={() => setShowSidebar(!showSidebar)}>
        Toggle sidebar
      </button>
      {showSidebar && <Sidebar />}
    </div>
  );
};

Lazy loading is a technique that allows us to load a component only when it’s needed, like with the dynamic import above. This is useful for large applications that have many components that are not needed on the initial render. For example, if we have a large application with a collapsible sidebar that has a list of links to other pages, we might not want to load the full sidebar if it’s collapsed on first load. Instead, we can load it only when the user toggles the sidebar

Suspense

By wrapping the entire component in Suspense, we render the fallback until all asynchronous children (promises) are resolved. This means that the entire application is hidden until the sidebar is loaded. This can be useful if we want to wait until everything’s ready to reveal the user interface to the user, but in this case might not be the best idea because the user is left wondering what’s going on and they can’t interact with the application at all.

import { lazy, Suspense } from "react";

const Sidebar = lazy(() => import("./Sidebar"));

const MyComponent = () => {
  const [showSidebar, setShowSidebar] = useState(false);

  return (
    <div>
      <button onClick={() => setShowSidebar(!showSidebar)}>
        Toggle sidebar
      </button>
      <Suspense fallback={<p>Loading...</p>}>
        {showSidebar && <Sidebar />}
      </Suspense>
      <main>
        <p>Hello hello welcome, this is the app's main area</p>
      </main>
    </div>
  );
};