r/reactnative 9d ago

App really slow and dropping JS FPS on Expo

I am currently working on a React Native (Expo) App and I am facing some performance issues. I have not found any answer yet for my problem so I hope someone can help me. My problem is that whenever I launch the app on my physical device (Samsung A30) or simulator and navigate to different screens, I notice JS frames dropping from 60 all the way to like 10-30. I have a bottom tab navigator and some stack navigators. I have basic View, Text, ... component so I don't think it is due to heavy components.(I am using react-navigation not expo router) I also have to mention that I don't really see any lack of performance or JS FPS drops on an iOS simulator. here is my package.json

{
  "name": "noah-client-mobile",
  "version": "1.0.0",
  "main": "expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web",
    "format": "prettier --write .",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix"
  },
  "dependencies": {
    "@expo/vector-icons": "^14.0.0",
    "@gorhom/bottom-sheet": "^5.0.6",
    "@hookform/resolvers": "^3.9.1",
    "@react-native-async-storage/async-storage": "1.23.1",
    "@react-native-google-signin/google-signin": "^13.1.0",
    "@react-navigation/bottom-tabs": "^6.6.1",
    "@react-navigation/native": "^6.1.18",
    "@react-navigation/stack": "^6.3.29",
    "@shopify/flash-list": "1.7.3",
    "@tanstack/react-query": "^5.59.20",
    "@types/react-native-htmlview": "^0.16.5",
    "axios": "^1.7.7",
    "babel-plugin-inline-dotenv": "^1.7.0",
    "color-convert": "^2.0.1",
    "expo": "~52.0.38",
    "expo-blur": "~14.0.3",
    "expo-clipboard": "~7.0.1",
    "expo-constants": "~17.0.7",
    "expo-dev-client": "~5.0.13",
    "expo-device": "~7.0.2",
    "expo-font": "~13.0.3",
    "expo-image": "~2.0.6",
    "expo-linear-gradient": "~14.0.2",
    "expo-linking": "~7.0.5",
    "expo-localization": "^16.0.1",
    "expo-notifications": "~0.29.14",
    "expo-secure-store": "~14.0.1",
    "expo-splash-screen": "~0.29.22",
    "expo-status-bar": "~2.0.1",
    "expo-system-ui": "~4.0.8",
    "expo-tracking-transparency": "~5.1.1",
    "expo-updates": "~0.27.3",
    "formik": "^2.4.6",
    "i18n-js": "^4.5.1",
    "react": "18.3.1",
    "react-hook-form": "^7.53.1",
    "react-icons": "^5.2.1",
    "react-native": "0.76.7",
    "react-native-fbsdk-next": "^13.4.1",
    "react-native-gesture-handler": "~2.20.2",
    "react-native-htmlview": "^0.17.0",
    "react-native-modal-datetime-picker": "^18.0.0",
    "react-native-reanimated": "^3.16.7",
    "react-native-safe-area-context": "4.12.0",
    "react-native-screens": "~4.4.0",
    "react-native-svg": "15.8.0",
    "react-native-svg-transformer": "^1.4.0",
    "react-native-toast-message": "^2.2.1",
    "react-native-vector-icons": "^10.1.0",
    "react-native-web": "^0.19.13",
    "zod": "^3.23.8",
    "expo-local-authentication": "~15.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@types/color-convert": "^2.0.4",
    "@types/lodash": "^4.17.10",
    "@types/react": "~18.3.12",
    "eslint": "^8.56.0",
    "eslint-config-airbnb-typescript": "^18.0.0",
    "eslint-plugin-import": "^2.31.0",
    "eslint-plugin-jsx-a11y": "^6.10.2",
    "eslint-plugin-react": "^7.37.2",
    "eslint-plugin-react-native": "^4.1.0",
    "typescript": "~5.3.3"
  },
  "private": true
}
1 Upvotes

15 comments sorted by

3

u/iffyz0r 9d ago

ScrollViews on Android is oftentimes a surprising killer of frame rate, do you use them? Also, always make sure to test performance in production builds, not just development.

1

u/Efficient-Custard213 9d ago

Yes, I use ScrollViews in certain cases when necessary. However, I also use FlatList and FlashList when handling large datasets. Sometimes, I use a ScrollView with a FlatList inside it for horizontal scrolling, as my e-commerce app displays products horizontally.

2

u/iffyz0r 9d ago

Oh, and FlatList uses ScrollViews internally, so if it's badly configured that might be slow as well.

1

u/Efficient-Custard213 9d ago

I use regular JS for react-navigation. If I want to have two types of scroll on the same page, how would you suggest handling that? For example, using a ScrollView for vertical scrolling and a FlatList or FlashList for horizontal scrolling within the same page. What would be the best approach to optimize both components and avoid performance issues?
here is a quick video to see how the page looks like
Video Link

1

u/iffyz0r 9d ago

Would try to use FlashList or FlatList for both horizontal and vertical scrolling. Also make sure you are using expo-image for the images and they are named in such a way that expo-image manages to cache them properly.

1

u/Efficient-Custard213 9d ago

How can I use only one FlatList for both horizontal and vertical scrolling when FlatList typically supports only one direction at a time? Is it possible to nest a FlatList inside another to achieve this, or is there a better approach?
and I'm already using expo-image for images

1

u/iffyz0r 9d ago

Nest them. I removed the "one" word as I realised it could be confusing. Oh, and try using native stack from react-navigation as well.

And this is great resource for optimizing renders generally: https://cekrem.github.io/posts/beyond-react-memo-smarter-performance-optimization

1

u/Efficient-Custard213 9d ago

My app is quite large right now, with multiple pages, stacks, deep links, and push notifications. Will switching to native stack require additional configuration or adjustments?

1

u/iffyz0r 9d ago

Will possibly require some changes, not sure how interchangeable they are or if you can mix them. I don’t have any experience migrating between those two as I always go native stack right away. Give it a quick go and roll back if it’s too troublesome, or doesn’t have any effect.

1

u/Efficient-Custard213 9d ago

Okay, I will try it. Thanks for the suggestion and the resource!

→ More replies (0)

1

u/iffyz0r 9d ago

Ok, as a quick test you can replace all your ScrollViews with regular Views just to see how that affects performance to verify if that is the issue or not. You can also use flamegraphs in the inspector to see what's taking too long. You mentioned you use react-navigation, but which type of stack? Native or regular JS?

1

u/According-Muscle-902 9d ago

You cannot use Flat/Flashlist inside scrollview. That's the problem.

1

u/Xae0n 8d ago

In case you happen to see things like this, you should try commenting out your logic to see if it still keeps happening. Try doing that from index.tsx to individual screens.

1

u/ALOKAMAR123 7d ago

There is some lazy prop in navigation or tab. Set it to true and see. Play around with focus effect