Skip to content

Commit

Permalink
Document lazy-loading screens for web
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Jul 29, 2024
1 parent 8fb73d0 commit 5084392
Showing 1 changed file with 67 additions and 1 deletion.
68 changes: 67 additions & 1 deletion versioned_docs/version-7.x/web-support.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
---
id: web-support
title: React Navigation on the Web
title: React Navigation on Web
sidebar_label: Web support
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

React Navigation has built-in support for the Web platform. This allows you to use the same navigation logic in your React Native app as well as on the web. The navigators require using [React Native for Web](https://github.com/necolas/react-native-web) to work on the web.

## Pre-requisites
Expand All @@ -28,6 +31,69 @@ In React Navigation 4, it was necessary to install a separate package called `@r

:::

## Lazy loading screens

By default, screen components are bundled in the main bundle. This can lead to a large bundle size if you have many screens. It's important to keep the bundle size small on the web for faster loading times.

To reduce the bundle size, you can use [dynamic `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) with [`React.lazy`](https://react.dev/reference/react/lazy) to lazy load screens:

<Tabs groupId="config" queryString="config">
<TabItem value="static" label="Static" default>

```js name="Lazy loading screens" snack version=7
import { Suspense, lazy } from 'react';

const MyStack = createNativeStackNavigator({
screenLayout: ({ children }) => (
<Suspense fallback={<Loading />}>{children}</Suspense>
),
screens: {
Home: {
component: lazy(() => import('./HomeScreen')),
},
Profile: {
component: lazy(() => import('./ProfileScreen')),
},
},
});
```

</TabItem>
<TabItem value="dynamic" label="Dynamic">

```js name="Lazy loading screens" snack version=7
import { Suspense, lazy } from 'react';

const HomeScreen = lazy(() => import('./HomeScreen'));
const ProfileScreen = lazy(() => import('./ProfileScreen'));

function MyStack() {
return (
<Stack.Navigator
screenLayout={({ children }) => (
<Suspense fallback={<Loading />}>{children}</Suspense>
)}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
);
}
```

:::warning

Make sure to use `React.lazy` **outside** the component containing the navigator configuration. Otherwise, it will return a new component on each render, causing the [screen to be unmounted and remounted](troubleshooting.md#screens-are-unmountingremounting-during-navigation) every time the component rerenders.

:::

</TabItem>
</Tabs>

This will split the screen components into separate chunks (depending on your bundler) which are loaded on-demand when the screen is rendered. This can significantly reduce the initial bundle size.

In addition, you can use the [`screenLayout`](navigator.md#screen-layout) to wrap your screens in a [`<Suspense>`](https://react.dev/reference/react/Suspense) boundary. The suspense fallback can be used to show a loading indicator and will be shown while the screen component is being loaded.

## Web-specific behavior

Some of the navigators have different behavior on the web compared to native platforms:
Expand Down

0 comments on commit 5084392

Please sign in to comment.