App
App copied to clipboard
[$500] Android - Scan - Icons in Scan receipt context menu appear after delay
If you havenβt already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: v1.4.28.0 Reproducible in staging?: y Reproducible in production?: y If this was caught during regression testing, add the test name, ID and link from TestRail: Email or phone of affected tester (no customers): Logs: https://stackoverflow.com/c/expensify/questions/4856 Expensify/Expensify Issue URL: Issue reported by: Applause - Internal Team Slack conversation:
Action Performed:
- Go to 1:1 DM.
- Create a Scan request using receipt taken via device camera.
- Navigate to request details page.
- Manually enter the amount.
- Tap to open the receipt.
- Tap 3-dot menu while the receipt is still loading.
Expected Result:
The icons for Replace, Download and Delete receipt in the context menu will appear without delay.
Actual Result:
The icons for Replace, Download and Delete receipt in the context menu appear after delay.
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
- [x] Android: Native
- [ ] Android: mWeb Chrome
- [ ] iOS: Native
- [ ] iOS: mWeb Safari
- [ ] MacOS: Chrome / Safari
- [ ] MacOS: Desktop
Screenshots/Videos
Add any screenshot/video evidence
https://github.com/Expensify/App/assets/93399543/8ef5e857-ddd5-416a-bc10-88d182a50756
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~01d26562fb0814a7b3
- Upwork Job ID: 1749421771987537920
- Last Price Increase: 2024-02-05
Job added to Upwork: https://www.upwork.com/jobs/~01d26562fb0814a7b3
Triggered auto assignment to @zanyrenney (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
Triggered auto assignment to Contributor-plus team member for initial proposal review - @eVoloshchak (External
)
We think that this bug might be related to #wave5-free-submitters CC @dylanexpensify
Hey thanks @kbecciv let me check with Dylan!
agree!
it's been moved over, all good here. waiting on proposals!
Not overdue, waiting on proposals
π£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πΈ
awaiting propopsals.
@eVoloshchak @zanyrenney this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!
π£ It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? πΈ
bumped in open source room here https://expensify.slack.com/archives/C01GTK53T8Q/p1707218950335999
Proposal
Please re-state the problem that we are trying to solve in this issue
The icons for Replace, Download and Delete receipt in the three dots menu appear with a delay.
What is the root cause of that problem?
[!NOTE] This only happens on Android, where images are not cached as aggressively as on iOS by default.
https://github.com/Expensify/App/blob/6a0e7edf75478df8fe22525cd5890c3f5a66477d/src/components/ImageSVG/index.native.tsx#L1
On iOS / Android native platforms we render these svg icons using expo-image
as it can be seen in the code reference.
This difference in caching behavior means that on Android whenever an image component is mounted in the UI hierarchy, the images are reloaded rather than being served from cache. This can result in a noticeable flicker as the images are being loaded everytime the three dot menu is being opened while another image is loading in the background.
What changes do you think we should make in order to solve the problem?
expo-image
exposes a prop called cachePolicy which offers great caching options variety:
-
disk
- Image is queried from the disk cache if exists, otherwise it's downloaded and then stored on the disk. -
memory
- Image is cached in memory. Might be useful when you render a high-resolution picture many times. Memory cache may be purged very quickly to prevent high memory usage and the risk of out of memory exceptions. -
memory-disk
- Image is cached in memory, but with a fallback to the disk cache.
Since the default OS based caching is not doing enough on Android currently, my pick is the memory
cachePolicy since with this one images are cached in RAM, which results in faster access compared to disk cache.
However, memory is more limited and valuable on mobile devices compared to disk space, which can lead to high memory usage, but it is very effective in avoiding loading delays like the ones we're encountering.
In order to avoid high memory usage, expo-image
also exposes a method called clearMemoryCache() which allows us to perform memory cache clean-up. For this we will have a useEffect which returns the clean-up function whenever the Image component is unmounted, like so:
useEffect(() => {
const clearMemoryCache = () => Image.clearMemoryCache();
return () => {
clearMemoryCache();
};
}, []);
[!IMPORTANT] Watch the before / after videos frame by frame in order to see what happens with more accuracy.
Videos
Android: Native
Before | After |
---|---|
@eVoloshchak please review the proposal above
However, memory is more limited and valuable on mobile devices compared to disk space, which can lead to high memory usage, but it is very effective in avoiding loading delays like the ones we're encountering.
Agree with this, but Android devices generally have more RAM and we're going to be loading only a couple of small icons into the memory, so it shouldn't change the RAM usage that much
@ikevin127's proposal looks good to me! πππ C+ reviewed!
Triggered auto assignment to @MonilBhavsar, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
@ikevin127 Did you try disk
setting and if yes, how did it go? It had the same issue?
I wonder if using memory cache would impact device's performance if user has lots of attachments in chats.
and we're going to be loading only a couple of small icons into the memory,
We'll be loading all icons and SVG images with this component, no? And also SVG images shared in chat?
@MonilBhavsar Did not try disk
, looks like this would also work for our issue but it would considerably slow down the loading of the other icons which use the Icon component that renders the native version of ImageSVG.
I created a diff of videos with current / disk
/ memory
and this is how it looks:
[!NOTE] Currently, if we go frame by frame whenever the screens are mounted / change, you can notice the speed at which the icons load and on our issue's screen we can notice the delay.
When using
disk
we can even notice on the last screen of the video (this issue) that the goBack icon of the header doesn't load at all, even though this issue's bug seems to be fixed.When using
memory
we get the best of both worlds, the Icons are loading from memory which is the fastest possible method + our current issue is fixed, and we're using theImage.clearMemoryCache()
whenever that ImageSVG is un-mounted, ensuring we're not overloading memory.
Android: Native
Current | Disk | Memory |
---|---|---|
This is why I proposed to go with the memory
cache, in order to not mess with the rest of the icons while still fix this issue. We're only adding this logic to the index.native.tsx
of the ImageSVG component, therefore only for native devices.
For reference these are the components which use ImageSVG:
- Icon
- Breadcrumbs
- CardPreview
- ConfirmedRoute
- DistanceEReceipt
- ExpensifyWordmark
- DistanceRequestFooter
- QRShare
- SplashScreenHider
- GenericErrorPage
- ReceiptDropUI
- IOURequestStepScan
- Footer
- SignInPageLayout
All of these ImageSVG instances are rendering local svgs from the @assets folder.
We'll be loading all icons and SVG images with this component, no?
Yes, since on natives the Icon component uses the index.native.tsx
version of ImageSVG to render SVG's.
And also SVG images shared in chat?
Not sure about this one, from all the components mentioned above - all of these are rendering local @assets SVGs and nothing from a URI source which the images rendered in chat usually are (external uploads).
Thanks for the comparison and thoughts!
We're only adding this logic to the index.native.tsx of the ImageSVG component, therefore only for native devices.
Since the issue only happens with Android. How are we feeling about making change only to Android? Let's make sure we don't add regression to iOS.
π£ @ikevin127 π An offer has been automatically sent to your Upwork account for the Contributor role π Thanks for contributing to the Expensify app!
Offer link Upwork job Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review π§βπ» Keep in mind: Code of Conduct | Contributing π
Since the issue only happens with Android. How are we feeling about making change only to Android? Let's make sure we don't add regression to iOS.
@MonilBhavsar Sure, would it be acceptable if I simply clone the current index.native.tsx
which has a total of 21 lines:
https://github.com/Expensify/App/blob/6a0e7edf75478df8fe22525cd5890c3f5a66477d/src/components/ImageSVG/index.native.tsx#L1
and rename one to index.ios.tsx
and the other to index.android.tsx
, adding the mentioned logic only to Android ?
Yes, that's the way I can also think of π
@eVoloshchak PR https://github.com/Expensify/App/pull/36275 ready for review! π
Reviewing
label has been removed, please complete the "BugZero Checklist".
The solution for this issue has been :rocket: deployed to production :rocket: in version 1.4.42-5 and is now subject to a 7-day regression period :calendar:. Here is the list of pull requests that resolve this issue:
- https://github.com/Expensify/App/pull/36275
If no regressions arise, payment will be issued on 2024-02-26. :confetti_ball:
For reference, here are some details about the assignees on this issue:
- @eVoloshchak requires payment through NewDot Manual Requests
- @ikevin127 requires payment automatic offer (Contributor)
BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:
- [ ] [@eVoloshchak] The PR that introduced the bug has been identified. Link to the PR:
- [ ] [@eVoloshchak] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
- [ ] [@eVoloshchak] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
- [ ] [@eVoloshchak] Determine if we should create a regression test for this bug.
- [ ] [@eVoloshchak] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
- [ ] [@zanyrenney] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:
hey there
i can't get the offer to load for the payment, looking into it but sorry for the delay!
@eVoloshchak requires payment through NewDot Manual Requests - please request $500 @ikevin127 requires payment automatic offer (Contributor) - paid $500 through upwork.
thanks!
- The PR that introduced the bug has been identified. Link to the PR: there isn't a PR that has caused this, this was caused by images taking too long to load and not being cached
- The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment: N/A
- A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion: I don't think an additional discussion is needed here, this is a simple visual bug
- Determine if we should create a regression test for this bug. Is it easy to test for this bug? Yes Is the bug related to an important user flow? No Is it an impactful bug? No The bug is very minor and has zero impact on user experience, I don't think a regression test is needed here