Closed kbecciv closed 9 months ago
Triggered auto assignment to @michaelhaxhiu (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
Platforms
in OP are ✅)@michaelhaxhiu Whoops! This issue is 2 days overdue. Let's get this updated quick!
@michaelhaxhiu 6 days overdue. This is scarier than being forced to listen to Vogon poetry!
Job added to Upwork: https://www.upwork.com/jobs/~0156490fa397b075d8
Current assignee @michaelhaxhiu is eligible for the External assigner, not assigning anyone new.
Triggered auto assignment to Contributor-plus team member for initial proposal review - @robertKozik (External
)
This was tough to reproduce, but I got it eventually. Make sure to check/uncheck the task until there is a scroll bar in the thead, then scroll up so that you can't see new updates at the footer if you continue to check/uncheck
Indeed very tough to repro, I'll keep it under on radar and wait for any proposals 👌🏼
In task page, the page jitters when the user clicks(check & uncheck) the checkbox continuously. (Approximately, more than 10~14 times)
https://github.com/Expensify/App/blob/8dcad168d11a71424b6ffd7fa30fd1770c0165d5/src/components/InvertedFlatList/BaseInvertedFlatList.js#L136-L138
I think it's because of getItemLayout
in FlatList
.
Currently, we save size & offset of each item using measureItemLayout
function while rendering and we input them using getItemLayout
function in next rendering.
We use sizeMap
array to save size & offset of items.
But all these code was assumed and written as if new item will be added to the last element of the item array in FlatList
when the user adds a comment.
Actually, it will be added to first element of the item array.
We need to update getItemLayout
and measureItemLayout
functions based on correct mechanism.
const sizeMapIndex = this.props.data.length - index - 1;
We need to get index again in reverse order when we read & write size information of items with sizeMap
array.
And also offset of newly added item is 0.
I updated the code and I wasn't able to see jitter issue. Screencast from 2023年07月21日 16时46分54秒.webm
We may not use getItemLayout
in FlatList
. But it could affect performance for list of many items.
Hi @akamefi202, thanks for your proposal. First of all, I've tried to test your approach on my end, but it causes an error for me. I've attached a diff which I used.
Later, I'm not sure about the root cause you have written. As, most likely, you pinpointed the faulty code correctly, but you didn't provide an answer as to why it only occurs after spamming check/uncheck. If we were wrongly saving measurements, shouldn't it cause problems way earlier, not only after clicking multiple times?
diff --git a/src/components/InvertedFlatList/BaseInvertedFlatList.js b/src/components/InvertedFlatList/BaseInvertedFlatList.js
index d3fcda0ea5..e941933cec 100644
--- a/src/components/InvertedFlatList/BaseInvertedFlatList.js
+++ b/src/components/InvertedFlatList/BaseInvertedFlatList.js
@@ -53,13 +53,14 @@ class BaseInvertedFlatList extends Component {
* @return {Object}
*/
getItemLayout(data, index) {
- const size = this.sizeMap[index];
+ const sizeMapIndex = this.props.data.length - index - 1;
+ const size = this.sizeMap[sizeMapIndex];
if (size) {
return {
length: size.length,
offset: size.offset,
- index,
+ index: sizeMapIndex,
};
}
@@ -76,7 +77,7 @@ class BaseInvertedFlatList extends Component {
// initialRowHeight since we can only assume that all previous items
// have not yet been measured
offset: _.isUndefined(lastMeasuredItem) ? this.props.initialRowHeight * index : lastMeasuredItem.offset + this.props.initialRowHeight,
- index,
+ index: sizeMapIndex,
};
}
@@ -88,20 +89,22 @@ class BaseInvertedFlatList extends Component {
*/
measureItemLayout(nativeEvent, index) {
const computedHeight = nativeEvent.layout.height;
+ const sizeMapIndex = this.props.data.length - index - 1;
// We've already measured this item so we don't need to
// measure it again.
- if (this.sizeMap[index]) {
+ if (this.sizeMap[sizeMapIndex]) {
return;
}
- const previousItem = this.sizeMap[index - 1] || {};
+ const previousItem = this.sizeMap[sizeMapIndex - 1] || {};
// If there is no previousItem this can mean we haven't yet measured
// the previous item or that we are at index 0 and there is no previousItem
const previousLength = previousItem.length || 0;
const previousOffset = previousItem.offset || 0;
- this.sizeMap[index] = {
+ this.sizeMap[sizeMapIndex] = {
length: computedHeight,
offset: previousLength + previousOffset,
};
@robertKozik
About the code changes, we should use original index
when return size data. We should use sizeMapIndex
only for reading & writing sizeMap
array.
if (size) {
return {
length: size.length,
offset: size.offset,
index,
};
}
And offset
should be 0, when we return size data of newly added item.
About root cause, getItemLayout
is an optional optimization to improve performance of FlatList
when it contains so many items.
When FlatList
has only few items, it is enough to compute size of items correctly.
After many items are added to the list, the component start to refer the size data(which is not accurate now) to reduce time for the measurement of dynamic content.
So we see this issue after many items are added to the list.
One more thing is we're adding new items to invisible viewport when we check & uncheck the checkbox.
I think this is the reason why we see this issue only in task page.
The component gives priority to compute size of visible items and we're adding new items to invisible viewport.
So it might use wrong size data from sizeMap
array instead of computing size of new items.
This is just my analysis and other engineer might find more accurate reason.
But it's definitely clear that this issue is occurred by getItemLayout
and we can fix by updating getItemLayout
and measureItemLayout
functions.
@michaelhaxhiu, @robertKozik Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
After checking/unchecking the task the page jitter.
The heights/offsets of the elements in the inverted FlatList
are not calculated correctly. The full explanation for that is here. Previously, we addressed it by creating a BaseInvertedFlatList
component, but it doesn't work fully as expected.
Previously, we used the BaseInvertedFlatList
component for inverted lists, to make it work on the web. However, the react-native-web
library has addressed this issue related to the inverted
FlatLists in this PR.
Solution:
@expensify/react-native-web
with the latest changes from the necolas/react-native-web
repository.BaseInvertedFlatList
component.<BaseInvertedFlatList />
usages with:
<FlatList
inverted
{...otherProps}
/>
However, there are some dependency-related issues here.
We can add to the @expensify/react-native-web
fork changes only from this PR and replace BaseInvertedFlatList
with FlatList
with inverted
option.
I created a short PoC video showing the results.
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸
@akamefi202 Your proposal has some strange behaviour when the message list is very long:
https://github.com/Expensify/App/assets/61146594/a32dabd7-e281-4e91-a9f8-c72bd4b278d2
@kosmydel I think we have bumping the react-native-web
version in plans. If thats truly the case your proposal is better suited for this issue
@michaelhaxhiu @robertKozik 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!
Working on proposals 👀
@robertKozik Can we try to move to flashlist / recyclerlistview instead of using flatlist?
📣 @allroundexperts Please request via NewDot manual requests for the Contributor role ($1000)
📣 @usmantariq96 We're missing your Upwork ID to automatically send you an offer for the Reporter role. Once you apply to the Upwork job, your Upwork ID will be stored and you will be automatically hired for future jobs!
Thanks for your proposal @akamefi202. I'm not entirely convinced by the solution that you're proposing. I think if the upstream has a fix, we should go with that instead of updating our implementations.
I think @kosmydel's proposal has a better solution to fix the problem. Let's go with them.
🎀 👀 🎀 C+ reviewed
@kosmydel Before proceeding with updating react-native-web
, I think it would be better to start a discussion in the open-source
channel to see if we want to do a full blown upgrade (I fear that this will cause a lot of regressions) or just copying the changes from the PR you've mentioned.
Triggered auto assignment to @stitesExpensify, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
@michaelhaxhiu @allroundexperts @stitesExpensify this issue is now 3 weeks old. There is one more week left before this issue breaks WAQ and will need to go internal. What needs to happen to get a PR in review this week? Please create a thread in #expensify-open-source to discuss. Thanks!
Discussion ongoing on Slack.
I think that @kosmydel has the best proposal here, and we should wait for the react-native-web update before proceeding. That is in this issue which is also blocked, but we are very close to it being unblocked, so I think it's worth the wait.
Since this is on Hold, I'm gonna apply Weekly
label.
Note: I'm going to be OOO the next ~2 weeks and given this is on Hold, I'm not going to assign a BZ teammate because I feel like this won't be complete before I return. If I'm mistaken and this sees progress before I return, can you please remove my assignment & re-apply the Bug
label to assign a BZ that's online? Thanks!
Still on hold
hold
Triggered auto assignment to @adelekennedy (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
I'm re-assigning this to another BZ as part of my preparation for Sabbatical (starting Friday).
Next steps:
Monthly
as it's blocked, so please check to ensure we unblock when it's time.linked issue is still in progress
Hey, I've investigated this issue and it looks like it is fixed now. This PR introduced changes that I suggested in my proposal. I've retested this issue and for me, it doesn't occur anymore. I think we can close this one out.
cc @allroundexperts, @stitesExpensify, @adelekennedy
I can't reproduce so closing makes sense to me, gut check with you @allroundexperts
So in that case, can we close this issue? cc @adelekennedy, @allroundexperts, @stitesExpensify
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:
Expected Result:
Page should not start to jitter upon check and uncheck of checkbox.
Actual Result:
Page starts to jitter upon selection check and uncheck of checkbox.
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.3.39-5 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 Notes/Photos/Videos: Any additional supporting documentation
https://github.com/Expensify/App/assets/93399543/8401f72f-a157-44fc-84f3-75f2a2c30500
https://github.com/Expensify/App/assets/93399543/f4d8680e-7b8e-487a-9d96-2af02d4a2a36
Expensify/Expensify Issue URL: Issue reported by: @usmantariq96 Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1689069224351539
View all open jobs on GitHub
Upwork Automation - Do Not Edit