Status-react: [Perf] Test hypothesis 1: RN Bridge render bottleneck

Created on 9 Jan 2018  Â·  4Comments  Â·  Source: status-im/status-react

Identified Behavior

Toggling between chat list and chat tabs is noticeably laggy on many devices. Compare with Telegram e.g. Additionally, this might also impact other common transitions.

  • [x] Behavior has been confirmed to be part of MVP.
  • [x] Confirm this is still a problem for end users on our supported devices.

Hypothesis

Bad performance for toggling between tabs is due to RN Bridge roundtrips being a bottleneck for rendering.

(This is a common performance bottleneck for React Native programs.)

Assumptions

1) Assuming this is still a critical problem for end user
2) Assuming it is reasonably easy to fixable

Experiment

Use Spy or rn-snoopy to verify RN bridge roundtrips is the bottleneck.

Additionally, consider making use of re-frisk or manual timers to supplement above.

  • [x] This is the quickest way to test the hypothesis.

Acceptance critiera

  • [ ] Numbers on what is happening from user click on one tab to another, especially 80% effort
  • [ ] Understanding and write-up of the root cause
  • [ ] Specific issue suggestion on what code to implement to fix it
  • [ ] (Optionally) spike out potential solution and verify fix is working

Notes

See

performance

Most helpful comment

To sum up communication through RN bridge, we have the next types of messages:

  1. status-module
    The main concern was related to the way how we use web3, but it seems that regardless of number of incoming messages we don’t have more than 6-8 in/out RN bridge messages related to this module.

  2. Timing/JSTimers
    This module is used by animation (not native), when we call setTimeout/setInterval explicitly and under the hood by core.async. Right now we have 20-24 messages per second related to this module. So we can define a threshold about 50 mps which means that if we have more than 50 mps for this module something suspicious is happening, and this will trigger some notification in app (in dev mode).

  3. websocket
    Is used only in develop mode for dev tools and probably figwheel/re-frisk

  4. ui-manager
    Most of calls related to this module happen on navigation. As far as I can say we have something similar to direct dependency between the number of these calls and duration of navigation between screens. We also can define a threshold for this type of messages, I suppose that it should be about 40 for Android and ~100 on iOS. That’s the numbers when delay before rendering a new screen starts being noticeable (anyway exact numbers TBD)

| ___________________ | ____________develop___________ | experiment/nav-groups
|- | ---- | ---- |
chats -> console chat | updateView 7 createView   205 setChildren  159 Total: 373 | updateView 12 Create view 80  setChildren 58  Total: 150
chats -> profile | updateView 10 createView 89 setChildren 62 Total: 161 | updateView 12 createView 9 setChildren 5 Total: 26
profile -> chats | updateView 10 Createview 58 setChildren. 41 Total: 109 | updateView 12 createView 10 setChildren 6 Total: 28

  1. touches
    These messages happen when we touch screen, so if we touch it a lot there can be a lot of them but I doubt that they have serious impact on perf.

  2. native-animation
    Messages related to animation with setNativeDriver=true.

  3. keyboard-observer
    We explicitly call this module once in root element, then it also is called by FlatList. Nothing important, but it looked for suspicious at first glance because I was under impression the we call it for no reason. But we don’t.

  4. There are also different messages similar to
    RCTEventEmitter.receiveEvent([23,”topLayout"
    Many of them happens when animation with setNativeDriver=false is used, so in most cases we can notice same stuff by watching Timing/JSTimers

All 4 comments

@rasom Do you want to own this issue? Do you agree with it?

@annadanchenko Concurrently with testing of this hypothesis, can you please confirm this is still a problem for end users on our supported devices?

@oskarth yes and yes

Use Spy or rn-snoopy to verify RN bridge roundtrips is the bottleneck.

One problem with this experiment setup is that a lot of calls, as @rasom pointed out, aren't bidirectional, e.g. some are async/unidirectional. This means it isn't always straightforward to see what the cost of each "bridge crossing".

@rasom You've posted a bunch of observations from this in Slack, would you mind posting a summary of things you found in this issue so we don't lose it?

To sum up communication through RN bridge, we have the next types of messages:

  1. status-module
    The main concern was related to the way how we use web3, but it seems that regardless of number of incoming messages we don’t have more than 6-8 in/out RN bridge messages related to this module.

  2. Timing/JSTimers
    This module is used by animation (not native), when we call setTimeout/setInterval explicitly and under the hood by core.async. Right now we have 20-24 messages per second related to this module. So we can define a threshold about 50 mps which means that if we have more than 50 mps for this module something suspicious is happening, and this will trigger some notification in app (in dev mode).

  3. websocket
    Is used only in develop mode for dev tools and probably figwheel/re-frisk

  4. ui-manager
    Most of calls related to this module happen on navigation. As far as I can say we have something similar to direct dependency between the number of these calls and duration of navigation between screens. We also can define a threshold for this type of messages, I suppose that it should be about 40 for Android and ~100 on iOS. That’s the numbers when delay before rendering a new screen starts being noticeable (anyway exact numbers TBD)

| ___________________ | ____________develop___________ | experiment/nav-groups
|- | ---- | ---- |
chats -> console chat | updateView 7 createView   205 setChildren  159 Total: 373 | updateView 12 Create view 80  setChildren 58  Total: 150
chats -> profile | updateView 10 createView 89 setChildren 62 Total: 161 | updateView 12 createView 9 setChildren 5 Total: 26
profile -> chats | updateView 10 Createview 58 setChildren. 41 Total: 109 | updateView 12 createView 10 setChildren 6 Total: 28

  1. touches
    These messages happen when we touch screen, so if we touch it a lot there can be a lot of them but I doubt that they have serious impact on perf.

  2. native-animation
    Messages related to animation with setNativeDriver=true.

  3. keyboard-observer
    We explicitly call this module once in root element, then it also is called by FlatList. Nothing important, but it looked for suspicious at first glance because I was under impression the we call it for no reason. But we don’t.

  4. There are also different messages similar to
    RCTEventEmitter.receiveEvent([23,”topLayout"
    Many of them happens when animation with setNativeDriver=false is used, so in most cases we can notice same stuff by watching Timing/JSTimers

Was this page helpful?
0 / 5 - 0 ratings

Related issues

churik picture churik  Â·  3Comments

andmironov picture andmironov  Â·  3Comments

yevh-berdnyk picture yevh-berdnyk  Â·  4Comments

andytudhope picture andytudhope  Â·  4Comments

annadanchenko picture annadanchenko  Â·  3Comments