feat(chat): improve messages rendering (#21323)
* feat(chat): improve messages rendering This commit adds memoization and comparsion functions to the chat pages and chat messages to prevent whole chat re-renders and unnecessary message re-renders caused by React's default shallow comparsion mechanism. The comparsion functions ensure that only the pertinent message attributes trigger a component's re-render. Messages sent by a user are not updated (re-rendered) when their role change. In other words, the chat messages reflect the user's role at the time the message was sent. Altering the message to reflect the user's current role could confuse participants, as it would modify the context of the past conversation. This behavior has been validated by the UI/UX team and brings benefits such as performance improvements and consistent behavior with how playback handles such messages. * fix linter errors
This commit is contained in:
parent
09fcb3ad42
commit
1dbc773aee
@ -1,4 +1,9 @@
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import React, {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import { UpdatedEventDetailsForChatMessageDomElements } from 'bigbluebutton-html-plugin-sdk/dist/cjs/dom-element-manipulation/chat/message/types';
|
||||
import { Message } from '/imports/ui/Types/message';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
@ -304,4 +309,12 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatMesssage;
|
||||
function areChatMessagesEqual(prevProps: ChatMessageProps, nextProps: ChatMessageProps) {
|
||||
const prevMessage = prevProps?.message;
|
||||
const nextMessage = nextProps?.message;
|
||||
return prevMessage?.createdAt === nextMessage?.createdAt
|
||||
&& prevMessage?.user?.currentlyInMeeting === nextMessage?.user?.currentlyInMeeting
|
||||
&& prevMessage?.recipientHasSeen === nextMessage.recipientHasSeen;
|
||||
}
|
||||
|
||||
export default memo(ChatMesssage, areChatMessagesEqual);
|
||||
|
@ -1,5 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import React, {
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
memo,
|
||||
} from 'react';
|
||||
import { PluginsContext } from '/imports/ui/components/components-data/plugin-context/context';
|
||||
import { UpdatedEventDetailsForChatMessageDomElements } from 'bigbluebutton-html-plugin-sdk/dist/cjs/dom-element-manipulation/chat/message/types';
|
||||
import { HookEvents } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/enum';
|
||||
@ -35,6 +40,20 @@ interface ChatListPageProps {
|
||||
scrollRef: React.RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const areChatPagesEqual = (prevProps: ChatListPageProps, nextProps: ChatListPageProps) => {
|
||||
const nextMessages = nextProps?.messages || [];
|
||||
const prevMessages = prevProps?.messages || [];
|
||||
if (nextMessages.length !== prevMessages.length) return false;
|
||||
return nextMessages.every((nextMessage, idx) => {
|
||||
const prevMessage = prevMessages[idx];
|
||||
return (prevMessage.messageId === nextMessage.messageId
|
||||
&& prevMessage.createdAt === nextMessage.createdAt
|
||||
&& prevMessage?.user?.currentlyInMeeting === nextMessage?.user?.currentlyInMeeting
|
||||
&& prevMessage?.recipientHasSeen === nextMessage?.recipientHasSeen
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const ChatListPage: React.FC<ChatListPageProps> = ({
|
||||
messages,
|
||||
messageReadFeedbackEnabled,
|
||||
@ -86,6 +105,8 @@ const ChatListPage: React.FC<ChatListPageProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const MemoizedChatListPage = memo(ChatListPage, areChatPagesEqual);
|
||||
|
||||
const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
page,
|
||||
pageSize,
|
||||
@ -128,7 +149,7 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
}
|
||||
setLoadedMessageGathering(page, chatMessageData);
|
||||
return (
|
||||
<ChatListPage
|
||||
<MemoizedChatListPage
|
||||
messages={chatMessageData}
|
||||
lastSenderPreviousPage={lastSenderPreviousPage}
|
||||
messageReadFeedbackEnabled={isPrivateReadFeedbackEnabled}
|
||||
|
Loading…
Reference in New Issue
Block a user