Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blank screen during transition #377

Closed
iclems opened this issue Feb 22, 2017 · 14 comments
Closed

Blank screen during transition #377

iclems opened this issue Feb 22, 2017 · 14 comments

Comments

@iclems
Copy link
Contributor

iclems commented Feb 22, 2017

Issue Description

Also see: aksonov/react-native-router-flux#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.

Steps to Reproduce / Code Snippets

react-native-router-flux scenes where the destination is a GiftedChat

Expected Results

The GiftedChat should ideally render before the transition to be visible. At least parts of the UI should be there.

Additional Information

  • react-native-router-flux v3.37.0
  • react-native v0.41.2
  • react-native-gifted-chat version: 0.1.0
  • Platform(s) (iOS, Android, or both?): both
@kfiroo
Copy link
Collaborator

kfiroo commented Feb 22, 2017

@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

@iclems
Copy link
Contributor Author

iclems commented Feb 22, 2017

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.

@iclems
Copy link
Contributor Author

iclems commented Feb 22, 2017

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.

@iclems
Copy link
Contributor Author

iclems commented Feb 22, 2017

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.

@kfiroo
Copy link
Collaborator

kfiroo commented Feb 23, 2017

@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 :)

@iclems
Copy link
Contributor Author

iclems commented Feb 23, 2017

Thanks for those details! It seems like the right way to go. I'd add 2 things after having read more carefully about this:

  • The React Native team seems to be adding support for the navigator transitions via the native driver soon. This could help solve this issue at the native level.
  • Considering my way around this through a delay, it works well 90% of the time. Here's how I think most apps solve this (and it will be even better if we actually implement what you mentioned):
  • In GiftedChat, disable InteractionManager.runAfterInteractions and move to initialized asap on initial layout
  • In your router, use "applyAnimation" for the transition to GiftedChat and add a delay before the transition begins:
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:

  • Shouldn't there be a way to cache for an extended period the avatars? (e.g. my URLs are unique)
  • Would you be OK with introducing an option to disable InteractionManager.runAfterInteractions?
  • I'll try to do more profiling when I have time but my solution is a decent way around it in the short-term. The only issue is that technically the "delay" I introduce should be "start animation once Component is ready". The delay is likely device dependent...

@kfiroo
Copy link
Collaborator

kfiroo commented Feb 23, 2017

  • Removing InteractionManager.runAfterInteractions seems like the way to go, unless it really messes up something that I've missed - can you submit a PR? :)
  • The delay with the navigation is out of scope for this project, it is completely project dependant, some users might not even use navigation at all. You can implement this in your own navigator implementation in a way that is reasonable for your app. (btw, I'm not sure why that delay would make any difference, can you explain?)
  • About caching avatars, also, I feel it is out of scope for this project. react-native has some sort of cache for network requests, something like the browser probably. If you need real caching you can check out this repo https://github.com/kfiroo/react-native-cached-image

@iclems
Copy link
Contributor Author

iclems commented Feb 23, 2017

  • Removing 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.
  • I agree the delayed navigation is out of scope. I just want to document for future developers who may experience transitions not smooth enough. Combined with removing 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.
  • I will look into better caching. Thank you.

@gameboyVito
Copy link

@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.

@luco
Copy link

luco commented Jun 14, 2017

+1 on this.
Removing GiftedChatInteractionManager.runAfterInteractions(() did the trick. However, it would be nice if we had a better approach on this.

@cooperka
Copy link
Collaborator

cooperka commented Jul 9, 2017

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!

sondremare pushed a commit to EdtechFoundry/react-native-gifted-messenger that referenced this issue Oct 23, 2017
* [Request] Add prop for tintColor for ActionSheet in Actions FaridSafi#185

Add prop optionTintColor for ActionSheet options text

* Update default optionTintColor to native color

* Initial support tick messages

* The message sent and delivered props have been removed from GiftedChat and are now read from the message state

* Added possibility to override the behaviour of renderTicks, deleted nested function in renderTicks

* Updated example and ticks on the right the time and ticks only appear for the sent messages

* renderTick: Move the constant declaration to the top of the function

* Expose GiftedAvatar

* renderTick: Possibility to change style of the ticks passing the parameter tickStyle to GiftedChat

* Change the new messages' ids

Now are UUIDs generated with `node-uuid` and is possible to change this
behavior using `messageIdGenerator` prop.

* fixed chat height bug

* Refactor utils into stand-alone functions

* Improve readability of utils

* Keep improving readability of utils

* Add utils to root exports

* Add prop onInputTextChanged on GiftedChat API and help fix FaridSafi#286

* Maintain backward compatibility with deprecation warning

* Add eslint script (extends airbnb + react + react-native)

Currently 506 errors, 7 warnings :D

* Upgrade to eslint config v0.2.3

Removed a few unnecessarily strict rules, so we're
down to 486 errors now.

* Add react-native-lightbox for enlarging chat images

* Add navigator to propTypes

* Use a commit hash to fix Lightbox warning [Android]

Currently the fix is unpublished.

* Remove touch events and external keyboard dependency

* Bump RN version

* Remove commented code

* Downgrade RN version

* Enabling access to Library

Example crashes when you want to choose an image via „choose from
library“ . Fixed that.  Example should work with this edit like
intended.

* Remove dependency from package.json

* Update property

Deprecated property true for keyboardShouldPersistTaps

* Update property for Gifted Chat

Deprecated property true for keyboardShouldPersistTaps

* Add 'onPressActionButton' prop

* Add 'imageProps' prop, passed through to <Image>

* Use 'lightboxProps' instead of just 'navigator'

* config ListView props support

* fix warning for Avatar

Warning: Failed prop type: Invalid prop `left` of type `object` supplied to `Avatar`, expected `number`.
Bad object: {
  "left": {
    "borderWidth": 1,
    "borderColor": "#236CC3"
  }
}

* avoid listViewProps to override render methd and datasources

* Add listViewPoprs description to README

* add listViewProps to default props and propTypes

* Downgrade RN version to original

* Update prop validation for keyboardShouldPersistTaps

* Update Readme

* Update RN version to 0.40

* readme for 0.1.0

* bump npm versions

* Improve send message performance

* add missing props to inner message components

* v0.1.0

* fix for npm dependency

* node-uuid -> uuid

* v0.1.1

* Create GiftedChatInteractionManager.js

* Update GiftedChat.js

* v0.1.2

* v0.1.3

* render avatar on top

* Remove duplicated enableEmptySections

* If the keyboard has been dismissed and the user sends a message, the text input tool bar can be rendered incorrectly due to the bottom offset

* Allow minimum input tool bar height to be configurable in properties

* Update Bubble.js

* Export MessageContainer in GiftedChat

* fix for _messageContainerRef === null

* Bubble.js: Default value for prop bottomContainerStyle

* Applying fixes per comments

* rename @exponent to @expo

* v0.1.4

* image source add number type

* formatting

* Bump react-native-communications version to 2.2.1

* Support for orientation changes.

Turned on onLayout handler for all platforms.

Android only: on-screen keyboard resized main container and has own height.
https://developer.android.com/training/keyboard-input/visibility.html
So for calculate the messages container height need ignore keyboard height.

* Fix messagesContainerHeight resetting on orientation change

By using the same formula for messagesContainerHeight
in onMainViewLayout as everywhere else.

* Factor out repeated math into getBasicMessagesContainerHeight()

* Factor out repeated math into getMessagesContainerHeightWithKeyboard()

* Add onPressAvatar prop

* Pass currentMessage to onLongPress callback

* Add maxLength parameter for Composer input

* fix-extra spacing shown when avatar is not rendered

* fix isSameDay function

* Update @expo/react-native-action-sheet

* incorporate review and documentation

* incorporate review

* Fix default rendering of avatars (FaridSafi#479)

* Default renderAvatar to undefined so that it renders by default

Fixes bug introduced in FaridSafi#447

* Ignore .idea for IntelliJ

* Commit yarn.lock files

No changes to dependencies

* Remove `runAfterInteractions` during init (FaridSafi#380)

Fixes FaridSafi#377.
Fixes FaridSafi#228.

* 0.1.5

* Upgrade all dependencies to latest

And RN v0.45 on the example app

* [Example] Remove extraneous files when installing

They get copied by Yarn, or libraries that publish their babel configs

* Temporarily fork shallowequal to get rid of babel config

dashed/shallowequal#14

* Upgrade shallowequal now that PR is merged

* Change deprecated View.propTypes to ViewPropTypes (FaridSafi#478)

* [Example] Migrate to react-native-maps (MapView was deprecated)

* [Example] Temporarily fork react-native-nav to update ViewPropTypes

jineshshah36/react-native-nav#17

* Temporarily fork RN-action-sheet for deprecated React.PropTypes

expo/react-native-action-sheet#51

* Update README with new RN dependency requirements

* Clean up README

* 0.2.0

* [Example] Run react-native upgrade for RN v0.45

* [Example] Add back RCTCameraRoll.xcodeproj for camera roll picker

* Replace deprecated `onChange` with `onContentSizeChange` (FaridSafi#500)

* Migrate from deprecated React.PropTypes to prop-types (FaridSafi#508)

* Commit new prop-types dependency in yarn.lock

* Fix URLs that get linkified but are missing a scheme (FaridSafi#506)

* Add code comment and error logging for MessageText.onUrlPress

* Clarify Android installation steps for CRNA/Expo (FaridSafi#482)

Explain that no native project changes are required in Create React Native App or Expo

* Fix janky fullscreen Lightbox images by using flex: 1 (FaridSafi#467)

Setting image to full width/height makes animation returning image to previous spot look extremely awkward. flex: 1 allows image to resize between thumbnail and fullscreen as was intended with lightbox.

* Add `timeFormat` prop (FaridSafi#273)

* Added property for time format

* Added property to readme

* Add `dateFormat` prop

* Add .watchmanconfig and README notes for local development

* [Example] Upgrade to RN v0.46 to verify compatibility

* 0.2.1

* Add some README badges

* 0.2.2

* Remove dead code introduced by FaridSafi#467 (FaridSafi#509)

* Add 'showUserAvatar' prop; don't render null avatars (FaridSafi#511)

* fix(Avatar): display user chat message avatar

- check if current message user has an avatar to display
- don't base the logic of the display of the avatar on the user object id

Issue: FaridSafi#495
Issue URL: FaridSafi#495

* Only return null if avatar is set to null (otherwise render initials)

* Add 'showUserAvatar' prop, default to false

* Rearrange existing propTypes to match the README

* Add missing props to GiftedChat root component

* 0.2.3

* Accept a 'text' prop to override the internal state (e.g. redux)

* Add Redux notes to the README

* 0.2.4

* Use both onChange and onContentSizeChange to support Android RN <0.46

* 0.2.5

* Fix call/text onPhonePress actions ordering (FaridSafi#521)

* Fix email sending recipient array (FaridSafi#522)

* Fix minor typo in README (FaridSafi#517)

* Fix `Linking.canOpenURL` usage (FaridSafi#516)

* Add children props to Send component (FaridSafi#487)

* Simplify logic for Send component children

* 0.2.6

* Add imperative focusTextInput() method

* 0.2.7

* Add `parsePatterns` prop for custom message links (FaridSafi#551)

* Add a more generic function prop `parsePatterns`

* Clean up README

* [Example] Don't remove extraneous git dir

Just in case someone is mistakenly trying to use symlinks with RN.

* [Example] Update path to scripts/react-native-xcode.sh for RN v0.46

* Use better doc link for onLongPress (FaridSafi#573)

* Fixed doc link for long press

* Hard-code date for code link

* rm test command

* clean up

* fix: use newer version of parsed-text which has fixed propTypes

* fix: use newer version of lightbox which has fixed propTypes

* fix: use newer invertible-scroll-view that has fixed propTypes for react 16

* fix: do not account for keyboard here, as we have our own component in differ which does that

* reimplement inputToolbar ref

* reimplement listview ref

* add proptype for renderSuggestions
@hegelstad
Copy link

hegelstad commented Jan 21, 2018

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.

@glenvollmer
Copy link

any update on this? still experiencing the white screen in the latest version

@glenvollmer
Copy link

....?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants