K. D.
K. D.

Reputation: 4219

Gatsby manual code splitting for single pages

I know that Gatsby uses code splitting to optimize bundles for each given page, but how do we deal with it when creating a page as a single page application (like mentioned in Client-only routes).

If I have an app.js like this (taken from the example):

import React from "react"
import { Router } from "@reach/router"
import Layout from "../components/Layout"
import Details from "../components/Details"
import Home from "../components/Home"
import Login from "../components/Login"
import PrivateRoute from "../components/PrivateRoute"
import Status from "../components/Status"

const App = () => (
  <Layout>
    <Status />
    <Router>
      <PrivateRoute path="/app/profile" component={Home} />
      <PrivateRoute path="/app/details" component={Details} />
      <Login path="/app/login" />
    </Router>
  </Layout>
)

export default App

How can we achieve code splitting for these routes? Let's say Details is a very expensive component. Now it would be bundled and loaded everytime, no matter if it will be rarely visited.

Can we come around this?

Upvotes: 1

Views: 1328

Answers (2)

Hoang Nguyen
Hoang Nguyen

Reputation: 71

You can use React.lazy: If Details is very expensive. Instead of

import Details from "../components/Details"

do

const Details = lazy(() => import("../components/Details"))

Note: you also need to add fallback component using Suspense:

  <Suspense fallback={<div>Loading...</div>}>
    <Router>
      <PrivateRoute path="/app/profile" component={Home} />
      <PrivateRoute path="/app/details" component={Details} />
      <Login path="/app/login" />
    </Router>
  </Suspense>

Check out React's official documentation: https://reactjs.org/docs/code-splitting.html#reactlazy

Upvotes: 2

EliteRaceElephant
EliteRaceElephant

Reputation: 8162

You should read this segment of their blog post. Here the important section:

gatsby-link and link rel="prefetch"

The Link component exported by gatsby ships with an IntersectionObserver. The behavior is two-fold:

An IntersectionObserver is registered for all links
    This will register an idle prefetch for a request for that link’s resources
    See the code for gatsby-link
On hover a fetch will be used to send a non-idle request for that link’s resources
    This will use an onMouseEnter prop to make the resources available via our internal loader
    See the code for gatsby-link

The solution is astonishingly simple:

Use a classic HTML a tag instead of Gatsby Link.

This way the prefetching is disabled as discussed in this issuee by the Gatsby project maintainers.

Upvotes: 0

Related Questions