Also see: https://github.com/aksonov/react-native-router-flux/issues/1647
During a transition from a list view into a gifted chat view, the view is not rendered until after the component has mounted and is in center stage. As a result, during the transition the screen remains blank. This is not related to the state being set in the constructor or componentWillMount. The input is not even visible.
react-native-router-flux scenes where the destination is a GiftedChat
The GiftedChat should ideally render before the transition to be visible. At least parts of the UI should be there.
@iclems This is a know issue with gifted-chat, it's been here for a while now, I hope we can get to it soon.
PR is welcome, btw :)
As you can see here the first render is always an empty view that waits for the transition to finish before measuring and rendering the chat content.
I believe it was meant to prevent frame drops when animating a lot of content
Thank you for pointing me in the right direction. I will test and figure out what's that helping with. I guess using a debounce you could render once before and then wait until it's complete to render again.
Interesting. I just ran tests removing the InteractionManager.runAfterInteractions wrapper and executing the setState directly and it works ok. Not perfectly smooth but not bad. I'll test to see if it'd be better were we able to compute the size without taking a first pass at render and onLayout.
To give context on alternative solutions, what other (non react native apps) do when the next view is resource intensive is pause for 100ms before starting the animation. I just can't figure out yet, especially using router-flux how you could "prepare" the component before starting the transition.
@iclems Thanks for the research! :)
What react-native has to offer in this area is pretty cool, the ListView itself, that holds the messages, has initialListSize and pageSize props which tell it how many items it should render on the first render and how many on subsequent renders.
If everything works fine, it should render initialListSize items when it mounts and the transition should go smoothly.
Note that the use of ListView here was introduced after the onInitialLayoutViewLayout was written so it might not be needed anymore (before all message were statically rendered into the view so a chat with 500 messages was hard to render).
One thing we should make sure to test, I think the ListView will try to render a new page on every animationFrame which means it will try to render messages during the transition, if this is the case we need a way around it.
I hope that helps :)
Thanks for those details! It seems like the right way to go. I'd add 2 things after having read more carefully about this:
function leftToRightDelayed(pos, navState) {
return Animated.sequence([
Animated.delay(100),
Animated.timing(pos, {
toValue: navState.index,
duration: 400
})
]).start()
}
The results are good. Obviously, the smoothest transition will only be provided once navigator transitions go native. On the flip side, I'm not sure the issue with GiftedChat is really about the number of messages as in my current implementation I've limited my pages to 20 messages. I could limit further but I don't think it's making such an impact. Probably, the loading of avatars which haven't been cached has an impact here. Hence my follow-up questions:
InteractionManager.runAfterInteractions seems like the way to go, unless it really messes up something that I've missed - can you submit a PR? :)InteractionManager.runAfterInteractions may lead to slightly not smooth transitions when using a navigator. I'm just mentioning the workaround for users facing this. But in my opinion it's better than not showing anything until after the transition completes. InteractionManager.runAfterInteractions, it helps by providing time for GiftedChat to render its first pages and do the required computations. The component will mount, render and only then the transition starts when GiftedChat has completed rendering everything. @kfiroo I think the real solution should be replacing the ListView with FlatList, and display a placeholder when the chat list is still rendering. Also, please consider using PureComponent instead of Component if possible, because it will dramatically reduce unnecessary re-render times to boost performance.
+1 on this.
Removing GiftedChatInteractionManager.runAfterInteractions(() did the trick. However, it would be nice if we had a better approach on this.
This is now fixed on master. As @iclems mentioned here, the change is a good workaround that should make things better for most people, but it could lead to slower animations in some cases. PRs to improve performance are always welcome!
I am still having this issue on 0.3.0.
When I am passing a empty array to messages, it works as expected.
However, when I pass an array with 8 elements as a prop, it doesn't work. Both the comments and the input field is white, until it appears with a flash some 200-400ms later.
Most helpful comment
@kfiroo I think the real solution should be replacing the ListView with FlatList, and display a placeholder when the chat list is still rendering. Also, please consider using PureComponent instead of Component if possible, because it will dramatically reduce unnecessary re-render times to boost performance.