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

[Gekidou] Add performance and code improvements around post_list #6113

Merged
merged 7 commits into from
Apr 4, 2022

Conversation

larkox
Copy link
Contributor

@larkox larkox commented Mar 31, 2022

Summary

Add several performance and code improvements.

Wait for comments for more details.

Release Note

None

@larkox larkox added the 2: Dev Review Requires review by a core commiter label Mar 31, 2022
if (myChannel) {
rolesArray.push(...myChannel.roles.split(' '));
}
export function observePermissionForChannel(channel: ChannelModel, user: UserModel, permission: string, defaultValue: boolean) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is nice, but I think we should move it to the queries folder and not in utils

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking the same. Will do.

Copy link
Contributor

@enahum enahum left a comment

Choose a reason for hiding this comment

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

do we need to add strictMode to <AnimatedFlatList> and other FlatLists?

} else if (offsetY === 0 && y !== 0) {
setOffsetY(y);
}
setEnableRefreshControl(y === 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

nice!!

Copy link
Contributor Author

@larkox larkox left a comment

Choose a reason for hiding this comment

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

Comments on the changes

@@ -80,7 +80,7 @@ function Uploads({
const style = getStyleSheet(theme);

const errorHeight = useSharedValue(ERROR_HEIGHT_MIN);
const containerHeight = useSharedValue(CONTAINER_HEIGHT_MAX);
const containerHeight = useSharedValue(files.length ? CONTAINER_HEIGHT_MAX : CONTAINER_HEIGHT_MIN);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what changed, but this was not being updated on the effect on the first render. Now it is initialized to the correct value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The result was that when opening the channel, the height was as if a file was uploaded.

Copy link
Contributor

Choose a reason for hiding this comment

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

how did you find out about this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know exactly the details. I was moving things around, and suddenly (I don't realize what the change must be) I started seeing the input box higher than usual. I realized it was the space of the uploads (it was not part of the textbox and was not reactive to clicks).
Changing the initial value (which makes sense by the way) fixed it.

@@ -99,7 +99,7 @@ const PostList = ({
const onScrollEndIndexListener = useRef<onScrollEndIndexListenerEvent>();
const onViewableItemsChangedListener = useRef<ViewableItemsChangedListenerEvent>();
const scrolledToHighlighted = useRef(false);
const [offsetY, setOffsetY] = useState(0);
const [enableRefreshControl, setEnableRefreshControl] = useState(false);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No need for a number, a boolean is enough for what we use it, and makes it easier to work with.

} else if (offsetY === 0 && y !== 0) {
setOffsetY(y);
}
setEnableRefreshControl(y === 0);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Depending on the offset was forcing us to recreate the onScroll callback. This allow us to avoid that, reducing the number of re-renders.

let threadCreatedByCurrentUser = false;
let rootPost: PostModel | undefined;
const myPosts = await queryPostsBetween(postsInThread.database, postsInThread.earliest, postsInThread.latest, null, currentUser.id, '', post.rootId || post.id).fetch();
function observeShouldHighlightReplyBar(currentUser: UserModel, post: PostModel, postsInThread: PostsInThreadModel) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are removing most of the from$ by using observers instead of fetches. This should be more reactive and robust.

permissions.push(Permissions.EDIT_OTHERS_POSTS);
}

cep = permissions.every((permission) => hasPermissionForChannel(channel, user, permission, false));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel this was not working at all (it was always returning true, since every element had a promise, which is distinct from null, therefore true). I tried to fix it.

prevCellKey={prevCellKey}
+ onCellLayout={this._onCellLayout}
onUpdateSeparators={this._onUpdateSeparators}
- onLayout={e => this._onCellLayout(e, key, ii)}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

From facebook/react-native@19cf702
A new onLayout method was being passed on every render.

};

-class CellRenderer extends React.Component<
+class CellRenderer extends React.PureComponent<
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use PureComponent to avoid re-renders. This has some creative convergence with facebook/react-native#31327

- leadingItem: props.item,
- },
- };
+ if (prevState.separatorProps.leadingItem !== props.item) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since separatorProps is an object, we only want to update it if it actually changed.

...restProps
} = this.props;

+ const renderer = strictMode ? this._memoizedRenderer : this._renderer;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

}
}
- return style;
+ if (changed) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Avoid sending new styles if there are no changes, to avoid re-renders.

@larkox
Copy link
Contributor Author

larkox commented Mar 31, 2022

As far as I know, strictMode is not necessary to avoid the re-renders we were experiencing. Not sure if it will have any other upside down the road, but right now is not necessary.

@@ -40,7 +44,12 @@ describe('components/channel_list', () => {
expect(wrapper.toJSON()).toBeTruthy();
});

it('should render team error', () => {
it('should render team error', async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think something was broken in the channel_list header index that was preventing the header from being rendered in the failure cases, that got fixed with the changes on the way we handle permissions.

These changes are to adapt to the test now showing the header, and showing it correctly.

@larkox larkox requested a review from enahum March 31, 2022 17:15
Copy link
Contributor

@enahum enahum left a comment

Choose a reason for hiding this comment

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

@larkox let's merge #6109 and then merge gekidou on this branch so that we can build it for testing

@larkox larkox added the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod mattermod removed the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod
Copy link
Contributor

Building app in separate branch.

@mattermod
Copy link
Contributor

@enahum enahum added the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod mattermod removed the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod
Copy link
Contributor

Building app in separate branch.

@mattermod
Copy link
Contributor

@enahum enahum added the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod
Copy link
Contributor

Building app in separate branch.

@mattermod mattermod removed the Build Apps for PR Build the mobile app for iOS and Android to test label Mar 31, 2022
@mattermod
Copy link
Contributor

@avinashlng1080 avinashlng1080 added 4: Reviews Complete All reviewers have approved the pull request and removed 2: Dev Review Requires review by a core commiter labels Apr 1, 2022
@enahum enahum merged commit d1322e8 into mattermost:gekidou Apr 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4: Reviews Complete All reviewers have approved the pull request release-note-none
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants