-
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
Optimization of mobile startup time #31776
Optimization of mobile startup time #31776
Conversation
src/libs/EmojiUtils.ts
Outdated
@@ -322,6 +322,9 @@ function getAddedEmojis(currentEmojis: Emoji[], formerEmojis: Emoji[]): Emoji[] | |||
* If we're on mobile, we also add a space after the emoji granted there's no text after it. | |||
*/ | |||
function replaceEmojis(text: string, preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE, lang: 'en' | 'es' = CONST.LOCALES.DEFAULT): ReplacedEmoji { | |||
// emojisTrie importing the emoji JSON file on the app starting and we want to avoid it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So instead of importing the whole file we wait until replaceEmojis
is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how much does this reduce startup time? Won't this affect user opening emoji picker as soon as app is loaded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shaves off 20-30% of the time. However, this doesn't mean the importing continues for the entire duration. It's more complex than that. In our case, it doesn't impact the start-to-use time in the area where we're currently applying it. At least I haven't seen it. Would be great if you could also test it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we've shifted the timing of importing this file from when the thread is busy to a time when it can run more smoothly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvement, we just need a C+ review and to link an issue.
@ Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good! Please complete author checklist
src/libs/EmojiUtils.ts
Outdated
@@ -322,6 +322,9 @@ function getAddedEmojis(currentEmojis: Emoji[], formerEmojis: Emoji[]): Emoji[] | |||
* If we're on mobile, we also add a space after the emoji granted there's no text after it. | |||
*/ | |||
function replaceEmojis(text: string, preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE, lang: 'en' | 'es' = CONST.LOCALES.DEFAULT): ReplacedEmoji { | |||
// emojisTrie importing the emoji JSON file on the app starting and we want to avoid it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how much does this reduce startup time? Won't this affect user opening emoji picker as soon as app is loaded?
src/components/Icon/BankIcons.ts
Outdated
if (bankName.startsWith('us bank') || bankName.startsWith('usbank')) { | ||
return isCard ? USBankCard : USBank; | ||
} | ||
function getAssetIcon(bankName: BankNameAndEmptyString, isCard: boolean): React.FC<SvgProps> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How did you test this function? Some tests steps would be appreciated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used scenario from this PR #27923
As it was about migrating that component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! 😄
src/components/Icon/BankIcons.ts
Outdated
function getAssetIcon(bankName: BankNameAndEmptyString, isCard: boolean): React.FC<SvgProps> { | ||
// Mapping bank names to their respective icon paths | ||
const iconMappings = { | ||
[BANK_NAMES.EXPENSIFY]: isCard ? require('@assets/images/cardicons/expensify-card-dark.svg') : require('@assets/images/bankicons/expensify.svg'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean that each time getAssetIcon
is called all these svgs are imported synchronously? Doesn't it make performance worse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About using absolute paths – they get cached and then referenced in subsequent uses. I'm not totally sure about paths with aliases like @assets/...
, since they're relative. But from my testing, I didn't notice any regression. That's probably because this particular icon isn't used too often, and only one icon is called at a time. Plus, I didn't see any increase in memory usage. So, I'm cautiously optimistic that these might get cached too.
@@ -322,6 +322,9 @@ function getAddedEmojis(currentEmojis: Emoji[], formerEmojis: Emoji[]): Emoji[] | |||
* If we're on mobile, we also add a space after the emoji granted there's no text after it. | |||
*/ | |||
function replaceEmojis(text: string, preferredSkinTone = CONST.EMOJI_DEFAULT_SKIN_TONE, lang: 'en' | 'es' = CONST.LOCALES.DEFAULT): ReplacedEmoji { | |||
// emojisTrie importing the emoji JSON file on the app starting and we want to avoid it | |||
const emojisTrie = require('./EmojiTrie').default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here, does it mean that emojisTrie
will be imported each time replaceEmojis
is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do not change the required path, it will return the same reference cached in the first load. At least, that's how I understand this after additional research and testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's cool, thanks!
🧪🧪 Use the links below to test this adhoc build on Android, iOS, Desktop, and Web. Happy testing! 🧪🧪
|
Hey @situchan, how is it going? I'm quite excited to see the result 😃 |
I've tried to run this on Desktop again, and it works okay for me, so it's probably just a glitch. |
Started another build https://github.com/Expensify/App/actions/runs/7047044234 |
🧪🧪 Use the links below to test this adhoc build on Android, iOS, Desktop, and Web. Happy testing! 🧪🧪 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good typescript-wise
please pull main & fix lint |
The conflicts appear every few minutes 😸 |
yes, there's light theme migration recently and they touch lots of files |
Reviewer Checklist
Screenshots/VideosAndroid: Nativeandroid.movAndroid: mWeb Chromemchrome.moviOS: Nativeios.moviOS: mWeb Safarimsafari.movMacOS: Chrome / Safariweb.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We did not find an internal engineer to review this PR, trying to assign a random engineer to #31787 as well as to this PR... Please reach out for help on Slack if no one gets assigned! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @perunt, this is very helpful
I forgot I was not assigned to the issue, added bug label and @situchan for payment later |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoa, really cool stuff!
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/johnmlee101 in version: 1.4.7-0 🚀
|
🚀 Deployed to production by https://github.com/yuwenmemon in version: 1.4.7-4 🚀
|
Details
Fixed Issues
$ #31787
PROPOSAL:
This PR introduces lazy loading for large JSON files, notably emoji data, and optimizes imports across the application.
The updates were made across all graphs. Some of the examples here:
Before
After
The testing was limited to a few devices, and further testing across a broader range is encouraged to validate these improvements.
Android: Observed 2x faster performance on devices ranging from HUAWEI P smart 2019 (low end) to Pixel 7 PRO.
iOS: iPhone 7 Pro showed a 2x + improvement in speed.
Tests
Offline tests
QA Steps
We need to double-check the places where we use EMOJI:
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop