Skip to content

[Performance] Cold start time is slow on Android #4027

Closed

Description

@marcaaron

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Action Performed:

  1. Log into the app
  2. Kill the app
  3. Start up the app again

Expected Result:

App should take a reasonable amount of time to boot back up

Actual Result:

App takes too long to boot up

Proposals (PLEASE READ)

This issue mainly affects native platforms. We don't have a specific target in mind of "how long it should take" and of course this will vary from device to device. But any proposals to this issue should provide clear evidence that the proposal will reduce boot time / cold start.

Workaround:

N/A

Platform:

iOS
Android

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

Activity

  1. added
    AutoAssignerTriageAuto assign issues for triage to an available triage team member
    on Jul 14, 2021
  2. MelvinBot commented on Jul 14, 2021

    @MelvinBot
    Contributor

    Triggered auto assignment to @JmillsExpensify (AutoAssignerTriage), see https://stackoverflow.com/c/expensify/questions/4749 for more details.

  3. removed
    AutoAssignerTriageAuto assign issues for triage to an available triage team member
    on Jul 14, 2021
  4. marcaaron commented on Jul 14, 2021

    @marcaaron
    ContributorAuthor

    @JmillsExpensify curious if you think it'd be valuable to maybe have a goal in mind for this and generally base that on some of our most used apps and how long they take to start? Otherwise, I think going for "general improvements" to boot time can work, but there are probably many factors that can move us closer to where we want to be.

  5. marcaaron commented on Jul 14, 2021

    @marcaaron
    ContributorAuthor

    Some conversation here on RAM bundles as it was suggested by @jsamr that we can use Repack for cross platform lazy loading of modules. This could in theory reduce the app start time. I like this idea, but needs some more investigation :)

  6. JmillsExpensify commented on Jul 15, 2021

    @JmillsExpensify
    Contributor

    @marcaaron Catching up here. I'm with you. I think we should be aiming for comparison with best-in-class. Slack and WhatsApp are the favorites, but I'm sure there are others we could include if needed.

    Then separately, posting on Upwork now.

  7. JmillsExpensify commented on Jul 15, 2021

    @JmillsExpensify
    Contributor

    Hi contributors! If you are coming from our Upwork posting, welcome! Make sure to post your proposal in this issue and then someone from our team will approve so we can hire you. Thanks!

  8. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Jul 15, 2021
  9. MelvinBot commented on Jul 15, 2021

    @MelvinBot
    Contributor

    Triggered auto assignment to @NikkiWines (Exported), see https://stackoverflow.com/c/expensify/questions/7972 for more details.

  10. 42 remaining items

  11. marcaaron commented on Aug 5, 2021

    @marcaaron
    ContributorAuthor

    hilarious idea: what if we captured a screenshot of the app upon close, and then just... showed that whole screenshot when you open the app, and while we're sorting out the background? It would give the impression of super instant responsiveness.

    LOL, but maybe something like it? I think we can just...

    • load the minimum amount of data required to create the LHN (e.g. only about 8 chats are visible for me on init on Android so why bother loading another 190 that are totally hidden from view?)
    • continue retrieving the rest of the reports after that happens

    The report summary list (if we start storing a minimal version of it) should tell us something about the order in which reports need to be shown then we can stagger the loading and rendering of anything not in view.

  12. quinthar commented on Aug 5, 2021

    @quinthar
    Contributor
  13. kidroca commented on Aug 6, 2021

    @kidroca
    Contributor

    One more thing that can be optimized is the chat loaded under the LHN
    On web/desktop you see LHN and you last chat
    But on mobile this chat is loaded while you don't see it at all

    It can be lazy loaded instead - either load/pre-render it after LHN is done, or load it when it is selected (only on small screens though)

  14. marcaaron commented on Aug 6, 2021

    @marcaaron
    ContributorAuthor

    It can be lazy loaded instead

    Recently added some code to load this only after the sidebar is loaded

  15. MelvinBot commented on Aug 9, 2021

    @MelvinBot
    Contributor

    @marcaaron Whoops! This issue is 2 days overdue. Let's get this updated quick!

  16. MelvinBot commented on Aug 11, 2021

    @MelvinBot
    Contributor

    @marcaaron Eep! 4 days overdue now. Issues have feelings too...

  17. marcaaron commented on Aug 11, 2021

    @marcaaron
    ContributorAuthor

    Still looking into this. Have a draft that reduces the number of reportActions_* keys on init that I hope will help boot time.

  18. marcaaron commented on Aug 12, 2021

    @marcaaron
    ContributorAuthor

    Grabbed a JS profile on startup for Android and just leaving a breakdown of what is happening in the time between metro loading the bundle and the app displaying the sidebar...

    Total time ~ 2.5 - 3 seconds

    2021-08-12_09-21-16

    Going block by block...

    271 ms - renderApplication.. I think this is just react native starting…

    211 ms - Looks like Onyx doing something there are some getItem calls - probably this is reading from AsyncStorage

    184 ms - About half of this time is spent parsing JSON the other half rendering something (probably the Expensify.js component)

    60 ms - SafeAreaProvider renders

    74 ms - HTML render engine provider

    128 ms - I’m a little unsure what this block of time is doing… invokeCallbackAndReturnFlushedQueue, something with callTimer. Those methods indicate that we are firing a callback in a JS timer (which requires some communication over the bridge - but doesn't look like anything really happens - maybe it's the network request queue doing the tick it does each second)

    124 ms - This block looks pretty similar to the previous except there is a JSON parse which makes me think we have a network request.

    172 ms - Navigation Container renders in this block

    612 ms - Largest block here.. we can see several “sendDataToConnection” calls so we are rendering the MainDrawerNavigator, DrawerView, Header, etc - react navigation stuff.

    431 ms - The Sidebar is rendering in this block

    216 ms - The sidebar seems to render again for some reason (probably it doesn’t need to)

    At this point the initial sidebar is “rendered” to the screen.

    Here's the profile:
    sampling-profiler-trace4670664525343774149-converted.json.zip


    Having a couple thoughts...

    1. We can try to limit the sidebar from rendering again and save that 200ms (not much but it's something)
    2. The react-navigation stuff is taking a pretty long time to init together with the sidebar (about 1 second) so anything we can do to make that faster would be good.

    It would be nice to compare this to a profile on iOS and see whether the JS there is taking a similar amount of time. But it seems like profiling Hermes on iOS doesn't work at all.

  19. marcaaron commented on Aug 13, 2021

    @marcaaron
    ContributorAuthor

    I'm going to close out this issue and create a new one so we can get some more eyes on the problem. Now that there is a reliable way to test changes I think this would be better as a rolling job where we accept all proposals that are clear improvements (something like 500ms or more and can be verified by anyone).

  20. kidroca commented on Aug 16, 2021

    @kidroca
    Contributor

    BTW I've tried removing screens/components to see how much different components affect loading, but I used the Timing:... logs

    I get this after a fresh login and then app restart

    Timing:expensify.cash.homepage_reports_loaded 5396

    I've removed all the navigators and screens besidese LHN and the ReportScreen and the time didn't change much

    The time dropped to 2833 only after I've removed the whole ReportScreen

    Timing:expensify.cash.homepage_reports_loaded 2833

    Even then I've seen the LHN maybe about a second earlier

    I'll try to run the same with the new performance metrics and post on the new ticket
    This should give an idea on how much is there to be gained

  21. marcaaron commented on Aug 16, 2021

    @marcaaron
    ContributorAuthor

    Not sure if it's relevant but that particular timing log only completes when an API request finishes ->

    Timing.end(CONST.TIMING.HOMEPAGE_REPORTS_LOADED);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions