In general, the problem is that we have an additional delay before transition’s animation starts. If we make transition faster it only will make it look jumpy.
re-frame
events do not add additional delay, at least there is no difference ifreact-navigation
is called directly or throughre-frame
event- in RN docs
TouchableOpacity
responding delay is mentioned as a possible reason for delays on transitions, but that’s not likely our case because js thread is usually not overloaded - removing backgrounds from different components on the screen doesn’t change anything, this means that overdraws do not contribute to this delay
- rewriting the whole screen so that it is represented as a single data structure and all subscriptions are registered only at the root component doesn’t have a noticeable effect on performance
- if some heavy screen is replaced with something like
then transition starts as fast as in native apps, which means that delay is caused by rendering of the view, specifically by the number of children components inside the view;; [react/view {:width 100 :height 100 :background-clor :black}]
what can be done
- unnecessary views should be removed, we have many “containers” which are not needed, like warpers for a group of views (which might help to logically separate that group but is not needed by screens scructure), wrappers around
text
elemets (in many cases text’sstyle
prop would be sufficient enough), etc, like https://github.com/status-im/status-react/blob/26bbac83bcdb2f8d2f898c20b3414c018ff47e45/src/status_im/ui/screens/wallet/components/views.cljs#L109 or https://github.com/status-im/status-react/blob/26bbac83bcdb2f8d2f898c20b3414c018ff47e45/src/status_im/ui/screens/wallet/components/views.cljs#L73 - make sure that only visible part of screen is rendered, e.g.
initialNumToRender
is used in flat list when necessary, etc - we can load some visible parts of screen only after
:component-will-mount
, so that these parts will not contribute to initial transition delay, but this again makes views look jumpy and probably can’t be used everywhere in the app - something like preloading of screens might be handy, but it is not implemented in react navigation and will probably require significant effort to be implemented properly Idea: Preloading · Issue #73 · react-navigation/rfcs · GitHub
- there is probably some way to improve performance on native side
Unfortunately I haven’t found a solution which would significantly improve nav transition perf and it seems here we are limited to what RN can provide us. Replacing SVG images with PNG helped a bit (because it reduced the number components on each screen), new version of react-navigation
is slightly faster as well, but in overall we run into RN’s limitations.