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

CRS-384 Upgrade react-virtuoso to v1 #694

Merged
merged 6 commits into from
Feb 24, 2021
Merged

CRS-384 Upgrade react-virtuoso to v1 #694

merged 6 commits into from
Feb 24, 2021

Conversation

ath92
Copy link

@ath92 ath92 commented Feb 5, 2021

Submit a pull request

CLA

  • I have signed the Stream CLA (required).
  • The code changes follow best practices
  • Code changes are tested (add some information if not applicable)

Description of the pull request

Upgrades react-virtuoso to the latest version available. A refactor of VirtualizedMessageList was required to adapt to the breaking changes introduced with this new version. In particular, some extra work was needed to handle the new way virtuoso deals with prepending messages.

Improvements:

  • VirtualMessageList works well with Message and FixedHeightMessage
  • Margins in the item content are handled
  • New reactions keep the list at the bottom (if already there)

Not included:

  • Images with no specified sizing displace the timeline. The same happens in non-virtualized mode.

Squash the commits before merging, a lot of back and forth.

@ath92 ath92 requested review from mahboubii and DanC5 February 5, 2021 13:41
}
/>
);
},
[MessageDeleted, customMessageRenderer, shouldGroupByUser],
[
MessageDeleted,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably remove MessageDeleted from dep array, it shouldn't change

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I'd remove this. Even if it shouldn't change this, it technically could, and it doesn't really hurt to have it in the dependencies array.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this raises a larger question of how we handle dependency arrays. On the react native side we only include the data that should actually trigger a new render during an app session, so we don't include things like prop UI components that don't change mid-session. Obviously native is a little different, but we definitely saw performance improvements and decreased re-renders upon getting stricter with the dependency arrays. @mahboubii do you have thoughts on whether or not to keep UI components in dependency arrays?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could be customers who change the UI props conditionally in their app but the performance gain from removing this dependency check is worth it IMO and we should move toward that path.
In the meantime since changing these effect dependencies are potentially a breaking change, let's leave it as is until the next major release.
we should make it clear for customers that UI prop overrides should not change after the first render of the app

Footer,
};
}, [
EmptyStateIndicator,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with EmptyState and Typing

@DanC5
Copy link
Contributor

DanC5 commented Feb 5, 2021

@ath92 I'll admit I don't have much background on this feature but it looks pretty good, will wait for Amin to check it out too. Though in the meantime can you replace @ts-ignore with @ts-expect-error? This will help us when we get to converting this file and will notify you if there's not a type error to follow.

@mahboubii
Copy link
Contributor

looks like the new scrollTo function also accepts smooth behavior

@codecov-io
Copy link

codecov-io commented Feb 8, 2021

Codecov Report

Merging #694 (7d79567) into master (d936e30) will decrease coverage by 0.07%.
The diff coverage is 62.50%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #694      +/-   ##
==========================================
- Coverage   85.87%   85.79%   -0.08%     
==========================================
  Files         154      155       +1     
  Lines        3108     3140      +32     
  Branches      746      754       +8     
==========================================
+ Hits         2669     2694      +25     
- Misses        327      332       +5     
- Partials      112      114       +2     
Impacted Files Coverage Δ
...c/components/MessageList/VirtualizedMessageList.js 50.00% <48.64%> (+3.06%) ⬆️
.../components/MessageList/usePrependMessagesCount.js 89.47% <89.47%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d936e30...7d79567. Read the comment docs.

@github-actions
Copy link

github-actions bot commented Feb 9, 2021

Size Change: +36 kB (2%)

Total Size: 1.54 MB

Filename Size Change
./dist/browser.full-bundle.js 736 kB +20.8 kB (2%)
./dist/browser.full-bundle.min.js 408 kB +13.4 kB (3%)
./dist/css/index.css 28.6 kB +7 B (0%)
./dist/css/index.min.css 23.8 kB +7 B (0%)
./dist/index.es.js 164 kB +882 B (0%)
./dist/index.js 166 kB +896 B (0%)
ℹ️ View Unchanged
Filename Size Change
./dist/css/index.js 21 B 0 B
./dist/i18n/en.json 902 B 0 B
./dist/i18n/fr.json 1.38 kB 0 B
./dist/i18n/hi.json 1.56 kB 0 B
./dist/i18n/it.json 1.33 kB 0 B
./dist/i18n/nl.json 1.31 kB 0 B
./dist/i18n/ru.json 1.62 kB 0 B
./dist/i18n/tr.json 1.32 kB 0 B

compressed-size-action

@ath92
Copy link
Author

ath92 commented Feb 9, 2021

I think I've addressed the comments in this review so far, but I'm running into an issue: sometimes the startReached callback is called twice (one after the other, so after the first promise resolves, the function is called again to load more items). This causes the list to jump to the latest set of items that has been loaded (because firstItemIndex is changed when the last set of messages is loaded).

I'm not sure why this happens - as far as I can tell we're not doing anything different from the examples provided on the Virtuoso website. Perhaps @petyosi has some idea on why this could be happening? (let me know if it makes more sense to try and create a more minimal example of the problem and open an issue in the virtuoso repo instead)

@petyosi
Copy link
Contributor

petyosi commented Feb 9, 2021

I think I've addressed the comments in this review so far, but I'm running into an issue: sometimes the startReached callback is called twice (one after the other, so after the first promise resolves, the function is called again to load more items). This causes the list to jump to the latest set of items that has been loaded (because firstItemIndex is changed when the last set of messages is loaded).

I'm not sure why this happens - as far as I can tell we're not doing anything different from the examples provided on the Virtuoso website. Perhaps @petyosi has some idea on why this could be happening? (let me know if it makes more sense to try and create a more minimal example of the problem and open an issue in the virtuoso repo instead)

I have been struggling with this problem in this issue: petyosi/react-virtuoso#281 - check if debouncing the callback handle won't resolve it. If not, a repro will help me. Notice that the OS matters - if you reproduce it on Mac, then you are probably facing something different.

@ath92
Copy link
Author

ath92 commented Feb 12, 2021

I have been struggling with this problem in this issue: petyosi/react-virtuoso#281 - check if debouncing the callback handle won't resolve it. If not, a repro will help me. Notice that the OS matters - if you reproduce it on Mac, then you are probably facing something different.

Got some time to look into this again: The issue I was seeing was unrelated to the issue you mentioned here (and unrelated to virtuoso), but caused by how we handle prepending items to our channel state.

In short: the promise that is returned by loadMore contains the amount of new messages, but those new messages aren't added to the channel state at exactly the moment the promise resolves: the actual state update is performed by a debounced loadMoreFinished function in the Channel component. In some cases, this caused the list to be re-rendered with new messages, while firstItemIndex was not yet updated, or the other way around (firstItemIndex already updated, but no new messages yet).

I pushed a workaround for this that doesn't depend on the timing of the loadMore promise resolving, but I'm not super happy with it because it's kinda complex. I don't immediately see an easier way to fix it though, but open to suggestions.

@petyosi petyosi marked this pull request as draft February 18, 2021 16:46
@petyosi petyosi changed the title CRS-384 Upgrade react-virtuoso CRS-384 Upgrade react-virtuoso to v1 Feb 22, 2021
@petyosi petyosi self-assigned this Feb 22, 2021
@petyosi petyosi marked this pull request as ready for review February 23, 2021 08:39
@petyosi
Copy link
Contributor

petyosi commented Feb 23, 2021

@mahboubii @DanC5 @virdesai please take a look

@petyosi
Copy link
Contributor

petyosi commented Feb 24, 2021

@DanC5 let's give this a review when possible

@petyosi petyosi mentioned this pull request Feb 24, 2021
3 tasks
@petyosi petyosi marked this pull request as draft February 24, 2021 10:53
@petyosi petyosi marked this pull request as ready for review February 24, 2021 16:32
@DanC5 DanC5 merged commit 18cdba0 into master Feb 24, 2021
@delete-merged-branch delete-merged-branch bot deleted the upgrade-virtuoso branch February 24, 2021 17:29
scrollSeekPlaceHolder,
Message = FixedHeightMessage,
Message = DefaultMessage,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing that a fixed height message might not be required anymore, is it possible to use the MessageTeam component in the virtualized list now?

Looks like this Message property requires a type with FixedHeightMessageProps still, so not sure how to do it...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petyosi can you speak to the feasibility of using our other Message UI components in the VL now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kainosnoema indeed, using "any" messages in the virtual list is something which we are looking into, but not yet ready to introduce as the default configuration. The part which does not work as smoothly as we wish is messages which contain img elements without a specified size. Such posts may cause the virtual list to "jump" when the image is loaded.

This being said, you can ignore the typing for now and try passing the plain message - we would love to get your feedback on the performance of that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petyosi thanks for the update. We're building our own custom message component and will be having photo galleries with a fixed height (when attachments are present), so don't think we'll run into the jumping issue. We'll give this a shot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants