-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
[Performance] Improve Android Cold Boot TTI (Time To Interactive) #4656
Comments
Triggered auto assignment to @bfitzexpensify ( |
Triggered auto assignment to @Luke9389 ( |
Upwork posting |
I've managed to hook the flipper plugin to print this information instead of the Alert https://github.com/oblador/react-native-performance/blob/master/packages/flipper-plugin-performance/README.md
You can mark more events and they would appear on the timeline as well e.g. report selected -> report rendered This also allows exporting and importing files to Flipper |
@kidroca is there some way to use Flipper on a release build? I've found that these metrics are much different on dev builds which is why the alert method is used here. |
Any updates made on the ReportScreen or it's children doesn't seem to affect this metric as the end mark for TTI happens before the ReportScreen mounts (or shortly after it starts mounting)
I'm not sure how, but it's probably possible, I remember I've done iOS prod builds where the dev menu is enabled I've added marks for ReportActionsView.
And here's the same for a DEV build
|
It's good to have the bundle optimized for release, but it takes time to download via the metro server. This is important when we are timing a cold start from app icon tap to interactive so release builds have been most reliable for me. That said, I don't mind if we enable this flipper plugin or add additional metrics if we think that will be helpful. |
@bfitzexpensify @Luke9389 just a heads up that we can accept multiple proposals for this one. I don't think there will be a single solution to this one so mainly looking to accept any proposal that can improve this metric (which could mean the issue has multiple assignees). |
Captured some more insights as to where we're spending time during init This is a PROD js build (from the dev menu - not a release build) I'm 99% sure the red 🔴 needles are showing initial script parse and execution. Though I couldn't find documentation confirming this.
We're seeing so far before the 1st needle because of the measures we've made, otherwise the timeline would start from the first needle Slightly before the 2nd 🔴 needle are the first Onyx calls, they are part of the initial script execution - 700ms past the 2nd 🔴 needle is the TTI event It's really easy to update the Onyx metrics to be captured using Here's the export from flipper, you'll need to have the |
From Marc's screen in the description the IMO we can use the debug build to test theories and then use the release build (before/after) to prove them |
I like the idea to capture Onyx metrics with the Flipper plugin. I haven't relied on them very much tbh so maybe having them enabled when
I think it's because the JS source is precompiled into bytecode for the release build when using Hermes engine? Which perhaps does not happen when we build the debug app. But unsure tbh.
I agree with this, but at the end of the day the release build never lies 😄 |
Sure thing — just let me know who we want to hire and I'll keep the posting open (same to you @Luke9389) |
Correct.
0.35 vs 4.2 is a big improvement. I'll check if there's some way to use Flipper to see the performance results of a release build An alternative is that a debug build can be configured to precompile JS the same way a release does. Saw that in one of the perf capturing tutorials, there's a gradle config about it. This would keep Flipper available, and skip having to create certificates to sign release builds I wonder why on iOS a dev build still seems significantly faster in every aspect |
Application bundling can be updated to use RAM bundles to improve TTI in general Related Article: https://reactnative.dev/docs/ram-bundles-inline-requires We load all the screens and navigators even though only 1 is used during init, and some might not be used at all in a single session My idea is to 1) make a crude check on potential improvements by removing all navigators but the MainDrawerNavigator During 1) We can also capture memory usage with/without navigators as besides TTI this should potentially improve memory by offloading unused screens |
I did some digging on RAM bundles at one point and the discovered they aren't compatible when using Hermes. Something something Inline requires should still work with Hermes (I know I read this somewhere but didn't think of any great ways to implement) so that's something we could try. I'd definitely be curious to know if there are some large libraries or things doing a lot of work that could be lazy loaded or deferred. As for |
I've submit a PR here to review the Onyx metrics inside Flipper: Expensify/react-native-onyx#101 |
It's not possible to use Flipper with a release build (or at least without tweaking too many things)
It's relatively easy to include a compiled bundle (bytecode) in the dev build (it's still not the same as running a release build, but comes close) There's a large piece of time where we just see the splash screen. The reason is on a debug build the app tries to connect to the metro server - from my observations the app waits for a connection for about 5-6 sec then continues to load the bundled bytecode
Something else we can see is where the To run a debug build with precompiled JS bytecode
project.ext.react = [
enableHermes: true, // clean and rebuild if changing
bundleInDebug: true,
]
|
This tool can help with tracking any large JS bundles, and it can be run with I've run it on Expensify and here's what I've found out
A tool like this usually helps with tracking packages that are added 2x. or not tree shaken properly
To track heavy work we can use the Hermes profiling flow, or capture more metrics with |
Let's maybe see if anyone wants to lead this up internally. There's a PR out that improved the TTI on Android by like 800ms atm. So unsure how much faster we are looking to make things beyond that. |
I know @AndrewGable has been talking with callstack so perhaps he'd be interested in taking this. |
I also just highlighted this issue in Slack as a performance issue in need or a volunteer. |
@marcaaron - which PR is that? #4656 (comment) |
This one here to lazy load navigation screens -> #10986 |
This comment was marked as resolved.
This comment was marked as resolved.
Noticing that this issue is eroding a bit and not getting much love. Maybe it's not clear what we are trying to achieve? Ideas for how to take action on this...
|
Triggered auto assignment to @abekkala ( |
Just throwing this out there ... we have this issue to enable the new architecture. Part of that architecture, maybe less-talked-about than the new Fabric renderer, is called TurboModules. With the traditional React Native architecture all native modules had to be loaded up-front before the app would load and the JavaScript would start running. With TurboModules, native modules are lazy-loaded – that should bring forth some "free" reductions in TTI on cold boots |
@roryabraham I feel like this issue live kind of in vacuum. Should we either make this a tracking issue for PRs/issues which are aimed to improve the app loading time or I think we might want to close this one out as Margelo already addressed some boot up changes and we might want to go in a direction of creating a specific issues for specific problems (similar as you have linked above - enable fabric to speed things up) This issue is from august 2021 so I feel like it is a bit out of context at the moment. I think we could close this out, if you agree, feel free to close this one out. |
@mountiny Agreed. I'll go ahead and link this one to the existing tracking issue. |
Idea for clearer deliverable ->
Part of the problem with this issue is it's not clear how much faster things should be and an audit of where things are at would be a good place to start. |
I agree @marcaaron, and think that this issue could be a great starting place. |
I think we talked about multiget on a few occasions but we never really gave it a chance and it might boost performance A brief summary of the idea is
|
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
What performance issue do we need to solve?
What is the impact of this on end-users?
The app takes a long time to become interactive on Android.
We know that the number of reports a user has can impact the severity.
List any benchmarks that show the severity of the issue
We can test this in an Android release build by using the
CAPTURE_METRICS=true
option in.env
file and looking at thetimeToInteractive
metric after booting up the app (must be previously signed in).Follow Instructions here:
https://github.com/Expensify/App/blob/main/PERFORMANCE.md#performance-metrics-opt-in-on-local-release-builds
Android app startup JS sampling profile to inspect in Chrome Dev Tools (Taken from a Galaxy S8):
sampling-profiler-trace4670664525343774149-converted.json.zip
There's also a lot of context in this issue.
Proposed solution (if any)
N/A
List any benchmarks after implementing the changes to show impacts of the proposed solution (if any)
N/A
Platform:
Where is this issue occurring?
Version Number:
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
Expensify/Expensify Issue URL:
View all open jobs on Upwork
Additional Proposal Notes
The text was updated successfully, but these errors were encountered: