enableFreeze does not work on Web (react-native-web)
hbomatt opened this issue ยท 5 comments
Description
I'm using React-Navigation v6 along with the latest version of react-native-screens
and have followed the react-freeze
Quick Start Guide for React-Navigation... but how can I tell that it's actually doing anything? enableFreeze(true);
seems to have zero effect on the app that I'm working on. I've just been testing on Web (react-native-web) initially...
- I don't see any
Freeze
components in the component hierarchy using React Developer Tools in Chrome, running on Web viareact-native-web
. - I don't see any new Suspense-related components after enabling
react-freeze
. - react-native-screens doesn't seem to provide a
freezeEnabled()
method, likescreensEnabled()
... - I haven't noticed any change in performance when doing tasks like resizing the browser window with a navigation backstack of 10+ screens.
Stepping into the enableFreeze call, I see:
export function enableFreeze(shouldEnableReactFreeze = true) {// noop
}
react-native-screens/src/index.tsx
Line 31 in bef0d67
I was surprised to see that the react-freeze
integration isn't compatible with react-native-web
apps that use react-native-screens
.
Is this a bug or by design?
Screenshots
Steps To Reproduce
- Call
enableFreeze(true);
during app startup. - Navigate around to add a dozen screen instances to your backstack.
- Resize browser window.
Expected behavior
Only the current screen and the previous screen re-render, the other screen instances in the backstack do not re-render.
Actual behavior
Every screen in the backstack re-renders, causing a severe performance hit (several seconds to re-render after browser window resizing on a MBP)
Reproduction
I don't believe a Snack repro is needed, the issue is clear when looking at the react-native-screens
source code for the enableFreeze
method - comparing index.tsx
(no-op) to index.native.tsx
(actually enables react-freeze
)
Platform
- iOS
- Android
- Web
- Windows
- tvOS
Workflow
- Managed workflow
- Bare workflow
Package versions
package | version |
---|---|
react-native | 0.67.2 |
@react-navigation/native | 6.0.8 |
@react-navigation/native-stack | n/a |
react-native-screens | 3.13.1 |
react-native-safe-area-context | 3.1.9 |
react-native-gesture-handler | 1.10.3 |
react-native-reanimated | 1.13.2 |
expo | n/a |
Hello @hbomatt ๐
Yes, all of your observations are correct and it's neither a bug nor by design. We just haven't managed to add react-freeze
support for react-native-web
yet. This is something we'll look into in the future. But I won't provide any estimations tho. Sorry!
Cheers
Hi @kacperkapusciak ๐๐ป
Thanks for the explanation! I totally understand, react-freeze
was released so recently I was surprised to even see the slick integration with react-native-screens
from the get-go. I'm extremely excited for the react-freeze
project's potential to help fix performance issues in an app with lots of complex screens & navigation backstacks that typically contain a lot of screen instances. For now, we'll start using it on Android, iOS, and potentially a few additional platforms. ๐๐ป
๐ค๐ป that we'll eventually be able to use it on Web as well ๐
Thank you for your (and the entire team's) contributions to react-native-screens
, react-freeze
, etc. ๐ ๐ ๐
Just for other devs that come across this issue, I ended up relying on react-native-screens
to handle freezing & thawing screens for native in an app built with react-navigation
and it's working very well. To improve performance in the same app on Web, I opted to create a react-native
component that handles the freezing & thawing logic by examining navigation state and toggling the <Freeze />
component's prop, as appropriate. If react-native-screens
adds support for Web in the future, there would be benefits to switch to using it instead - but in the meanwhile, you can definitely work around this and successfully use react-freeze
in your app on Web. Thanks!
hello @hbomatt
I looked at your changes, but it would destroy the useIsFocused of bottom-tabs.
hello @hbomatt I looked at your changes, but it would destroy the useIsFocused of bottom-tabs.
Thanks, that was a non-issue for us because we don't use a tabbed interface on Web, we do use a tabbed interface on iOS/Android/FireTV/etc. but that uses the native freeze support instead. I just used the custom freeze tweak specifically on Web in the non-tabbed UI. It was a product/design choice to have the tabbed UI on mobile and a non-tabbed UI on Web. I guess that saved us from encountering the problem you discovered ๐ Thanks!
The biggest pain with this custom freeze approach on Web was disabling the various hooks that would execute on pages in the backstack, for perf reasons, but that was a pretty straight-forward fix once we realized what was going on.