Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy Loaded Route Modules #10045

Merged
merged 68 commits into from
Mar 8, 2023
Merged

Lazy Loaded Route Modules #10045

merged 68 commits into from
Mar 8, 2023

Conversation

brophdawg11
Copy link
Contributor

@brophdawg11 brophdawg11 commented Feb 3, 2023

Add support for a route.lazy method to lazily load the "meat" of a route while still providing the "matching" information up front. This injects the lazy() call into the normal loading/submitting navigation flow internal to the router so we can provide first-class support for route-level code splitting. This ends up being cleaner/easier than doing it in user-land for a few reasons:

  • We can load at a more specific spot internal to the router
  • We can access the navigation AbortSignal in case the lazy() call gets interrupted
  • We can also load once and update the route so subsequent navigations don't have a repeated lazy() call
  • We don't have issue with knowing whether or not an errorElement exists since we will have updated the route prior to updating any UI state

Example

let routes = [{
  path: '/',
  lazy: () => import('./root.tsx')
}, {
  path: '/about',
  lazy: () => import('./about.tsx')
}];

Todo

  • Unit tests
  • Built-in Remix-style export mapping (default export -> element, ErrorBoundary -> errorElement)
    • For clarity this is going to be left to user-land

Reference Links

@changeset-bot
Copy link

changeset-bot bot commented Feb 3, 2023

🦋 Changeset detected

Latest commit: 2560422

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
react-router Minor
react-router-dom Minor
@remix-run/router Minor
react-router-dom-v5-compat Minor
react-router-native Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

packages/router/router.ts Outdated Show resolved Hide resolved
packages/router/router.ts Outdated Show resolved Hide resolved
packages/router/router.ts Outdated Show resolved Hide resolved
@remix-cla-bot
Copy link
Contributor

remix-cla-bot bot commented Feb 7, 2023

Thank you for signing the Contributor License Agreement. Let's get this merged! 🥳

docs/route/lazy.md Outdated Show resolved Hide resolved
docs/route/lazy.md Outdated Show resolved Hide resolved
docs/route/route.md Outdated Show resolved Hide resolved
docs/route/route.md Outdated Show resolved Hide resolved
docs/route/route.md Outdated Show resolved Hide resolved
@brophdawg11 brophdawg11 merged commit c56d84c into dev Mar 8, 2023
@brophdawg11 brophdawg11 deleted the brophdawg11/lazy-route-modules branch March 8, 2023 16:17
@brophdawg11
Copy link
Contributor Author

This is released in [email protected] if anyone is keeping an eye on this and wants to give it a test spin 😉

@davbrito
Copy link

davbrito commented Mar 10, 2023

How do you put a Suspense fallback for a lazy loaded route component?

@brophdawg11
Copy link
Contributor Author

That's not quite the "idiomatic" use case since the idea of lazy is to load the route definition before the render step, so you'd manage pending UI via useNavigation. However, if you want to route immediately and use Suspense you'd have to then also leverage defer so your data is Suspense-enabled. Here's a quick POC: https://codesandbox.io/s/route-lazy-suspense-ooru6p?file=/src/index.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants