Content-Length: 331602 | pFad | http://github.com/facebook/react-native/pull/49449

8C Make all React Native apps start 12% faster by mrousavy · Pull Request #49449 · facebook/react-native · GitHub
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

Make all React Native apps start 12% faster #49449

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

mrousavy
Copy link
Contributor

@mrousavy mrousavy commented Feb 15, 2025

Summary:

Okay the title is a bit clickbaity, but this is actually true. (on Android)

We (Janic, Szymon, Ruby and Me) discovered something interesting. React Native uses mmap for mapping the JS bundle to RAM, to avoid having to load the entire thing instantly at app startup.
Ruby doubted that this was true - so we investigated.

Apparently on Android, resources are compressed. And if the JS bundle is stored compressed, it has to be uncompressed before it can be loaded into RAM, hence not allowing it to be mmapp'ed! (see _CompressedAsset::getBuffer)

So with this PR, we now add .bundle files to noCompress in the react-native gradle plugin, which disables compression for the JS bundle.

In our tests, this improved TTI by 400ms!! (or 12%) 🤯🚀

NOTE: Yes, the .apk will now be bigger. But; Google Play compresses it anyways, so the download size of your .apk will likely not increase by much. It will be bigger on disk though.

Changelog:

[ANDROID] [CHANGED] Disable bundle compression to improve startup time

Test Plan:

1. Verify compression is disabled

Build two apps, one with this patch and one without. When I did this using the RN community template, the one without this patch was 47,6 MB, and the one with this patch was 48 MB in size. So the .apk got bigger, which is what we expected

2. Verify app startup is faster

Use tools like react-native-performance or custom markers to measure TTI. In our tests, we shaved off 400ms from the startup time, which was about 12%. (on a low-end Android device)

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Feb 15, 2025
@Abdel-Monaam-Aouini
Copy link

LGTM

@elicwhite
Copy link
Member

Iirc, there are a set of compressed assets in APKs that should be uncompressed on disk for fast app starts. The bundle is one of them. Nice find.

Is there a middle ground though rather than making apks all bigger? I believe in the FB app we have the bundle compressed in the apk and then on first launch we uncompressed it on disk. That makes all subsequent launches fast.

Is that a reasonable approach here?

@mrousavy
Copy link
Contributor Author

Is there a middle ground though rather than making apks all bigger? I believe in the FB app we have the bundle compressed in the apk and then on first launch we uncompressed it on disk. That makes all subsequent launches fast.

How would that be implemented? As in, added native code that manually uncompresses the bundle on first launch, writes the uncompressed data to disk (caches?) and then uses that for future launches? Or can you overwrite the existing compressed resource?

@elicwhite
Copy link
Member

elicwhite commented Feb 15, 2025

Yep, exactly like that. 🙂

I'm not sure how the ota clients like expo-updates work but you'd want to do that when the updates are downloaded too

@mrousavy
Copy link
Contributor Author

I think such a change would require significantly more effort - and I'm honestly not sure if it's worth the effort.

Download size is roughly the same with my PR, because Google Play compresses the .apk again, so the .bundle is compressed on their servers.
Users download roughly the same amount of MB.
Once they install the app, it uncompresses and is a bit larger now than it was before.

With your change, the uncompression is just delayed after the first launch, instead of before. Not sure if that really makes sense for the added complexity? Especially if you consider that this will be native code and could throw/crash.

@mrousavy
Copy link
Contributor Author

Btw for everyone else; you can pull in this change in your apps already by simply setting noCompress in your build.gradle. More info in this tweet

  android {
+   androidResources {
+     noCompress += ["bundle"]
+   }
  } 

@ahmdyasser
Copy link

I loved how you gave credit for all the team, keep the good work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/facebook/react-native/pull/49449

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy