Skip to content

Commit 5084392

Browse files
committed
Document lazy-loading screens for web
1 parent 8fb73d0 commit 5084392

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

versioned_docs/version-7.x/web-support.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
---
22
id: web-support
3-
title: React Navigation on the Web
3+
title: React Navigation on Web
44
sidebar_label: Web support
55
---
66

7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
710
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.
811

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

2932
:::
3033

34+
## Lazy loading screens
35+
36+
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.
37+
38+
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:
39+
40+
<Tabs groupId="config" queryString="config">
41+
<TabItem value="static" label="Static" default>
42+
43+
```js name="Lazy loading screens" snack version=7
44+
import { Suspense, lazy } from 'react';
45+
46+
const MyStack = createNativeStackNavigator({
47+
screenLayout: ({ children }) => (
48+
<Suspense fallback={<Loading />}>{children}</Suspense>
49+
),
50+
screens: {
51+
Home: {
52+
component: lazy(() => import('./HomeScreen')),
53+
},
54+
Profile: {
55+
component: lazy(() => import('./ProfileScreen')),
56+
},
57+
},
58+
});
59+
```
60+
61+
</TabItem>
62+
<TabItem value="dynamic" label="Dynamic">
63+
64+
```js name="Lazy loading screens" snack version=7
65+
import { Suspense, lazy } from 'react';
66+
67+
const HomeScreen = lazy(() => import('./HomeScreen'));
68+
const ProfileScreen = lazy(() => import('./ProfileScreen'));
69+
70+
function MyStack() {
71+
return (
72+
<Stack.Navigator
73+
screenLayout={({ children }) => (
74+
<Suspense fallback={<Loading />}>{children}</Suspense>
75+
)}
76+
>
77+
<Stack.Screen name="Home" component={HomeScreen} />
78+
<Stack.Screen name="Profile" component={ProfileScreen} />
79+
</Stack.Navigator>
80+
);
81+
}
82+
```
83+
84+
:::warning
85+
86+
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.
87+
88+
:::
89+
90+
</TabItem>
91+
</Tabs>
92+
93+
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.
94+
95+
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.
96+
3197
## Web-specific behavior
3298

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

0 commit comments

Comments
 (0)