Fix laggy scrolling on mobile app's home screen, etc. #4108
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Scrolling through some screens (such as the feed on the Home screen) in the Bluesky app is laggy on some mid- to low-end Android devices, with frame rates dropping below 30 FPS.
While not having a noticeable impact on iOS or high-end Android devices, this situation will start escalating to a severe level on mid- or low-end Android devices, giving the user a bad experience or even causing them to decide to switch to the web version instead to avoid the laggy scroll hurting their eyes.
Notably, this issue does not affect every scrollable List, such as the one on the Profile screen.
The small change in this PR improves performance by 200% on some Android devices
(worst case <15 FPS → worst case >30 FPS).
See screen recording: https://youtu.be/ipZeTkb2mAk
Cause and Solution
In the
List
component (src/view/com/util/List.tsx
), we have the following code:This might hurt performance since:
.onScroll
from thecontextScrollHandlers
object every time whenonScroll
is called may add influential computing overhead, as the handler may be called over 60 times per second.contextScrollHandlers
object from JS thread and passing it to the UI thread on every call adds overhead due to additional serializing and deserializing.(The above two points are assumptions, as I am unfamiliar with details on how worklet functions are serialized by reanimated or optimized by the JS runtime. Please correct me if I am wrong!)
(For the reason why this issue does not affect every
List
, I think it's because not everyList
is used with aonScroll
event handler in theScrollContext
)Solution
Destructure the
contextScrollHandlers
object beforehand to avoid repeated object access and unnecessary data transfer to the UI thread: