Additional render optimizations
This commit is contained in:
parent
6343e7c902
commit
7a8363c7c8
4 changed files with 93 additions and 70 deletions
|
@ -1,9 +1,10 @@
|
|||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { debounce, get, isNumber, pick } from 'lodash';
|
||||
import { debounce, get, isNumber, pick, identity } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import React, { CSSProperties, ReactChild, ReactNode } from 'react';
|
||||
import { createSelector } from 'reselect';
|
||||
import {
|
||||
AutoSizer,
|
||||
CellMeasurer,
|
||||
|
@ -214,6 +215,74 @@ type StateType = {
|
|||
lastMeasuredWarningHeight: number;
|
||||
};
|
||||
|
||||
const getActions = createSelector(
|
||||
// It is expensive to pick so many properties out of the `props` object so we
|
||||
// use `createSelector` to memoize them by the last seen `props` object.
|
||||
identity,
|
||||
|
||||
(props: PropsType): PropsActionsType => {
|
||||
const unsafe = pick(props, [
|
||||
'acknowledgeGroupMemberNameCollisions',
|
||||
'clearChangedMessages',
|
||||
'clearInvitedConversationsForNewlyCreatedGroup',
|
||||
'closeContactSpoofingReview',
|
||||
'setLoadCountdownStart',
|
||||
'setIsNearBottom',
|
||||
'reviewGroupMemberNameCollision',
|
||||
'reviewMessageRequestNameCollision',
|
||||
'learnMoreAboutDeliveryIssue',
|
||||
'loadAndScroll',
|
||||
'loadOlderMessages',
|
||||
'loadNewerMessages',
|
||||
'loadNewestMessages',
|
||||
'markMessageRead',
|
||||
'markViewed',
|
||||
'onBlock',
|
||||
'onBlockAndReportSpam',
|
||||
'onDelete',
|
||||
'onUnblock',
|
||||
'removeMember',
|
||||
'selectMessage',
|
||||
'clearSelectedMessage',
|
||||
'unblurAvatar',
|
||||
'updateSharedGroups',
|
||||
|
||||
'doubleCheckMissingQuoteReference',
|
||||
'onHeightChange',
|
||||
'checkForAccount',
|
||||
'reactToMessage',
|
||||
'replyToMessage',
|
||||
'retrySend',
|
||||
'showForwardMessageModal',
|
||||
'deleteMessage',
|
||||
'deleteMessageForEveryone',
|
||||
'showMessageDetail',
|
||||
'openConversation',
|
||||
'showContactDetail',
|
||||
'showContactModal',
|
||||
'kickOffAttachmentDownload',
|
||||
'markAttachmentAsCorrupted',
|
||||
'showVisualAttachment',
|
||||
'downloadAttachment',
|
||||
'displayTapToViewMessage',
|
||||
'openLink',
|
||||
'scrollToQuotedMessage',
|
||||
'showExpiredIncomingTapToViewToast',
|
||||
'showExpiredOutgoingTapToViewToast',
|
||||
|
||||
'showIdentity',
|
||||
|
||||
'downloadNewVersion',
|
||||
|
||||
'contactSupport',
|
||||
]);
|
||||
|
||||
const safe: AssertProps<PropsActionsType, typeof unsafe> = unsafe;
|
||||
|
||||
return safe;
|
||||
}
|
||||
);
|
||||
|
||||
export class Timeline extends React.PureComponent<PropsType, StateType> {
|
||||
public cellSizeCache = new CellMeasurerCache({
|
||||
defaultHeight: 64,
|
||||
|
@ -728,6 +797,8 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
const messageId = items[itemIndex];
|
||||
stableKey = messageId;
|
||||
|
||||
const actions = getActions(this.props);
|
||||
|
||||
rowContents = (
|
||||
<div
|
||||
id={messageId}
|
||||
|
@ -737,7 +808,7 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
role="row"
|
||||
>
|
||||
<ErrorBoundary i18n={i18n} showDebugLog={() => window.showDebugLog()}>
|
||||
{renderItem(messageId, id, this.resizeMessage, this.getActions())}
|
||||
{renderItem(messageId, id, this.resizeMessage, actions)}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
|
@ -1481,66 +1552,4 @@ export class Timeline extends React.PureComponent<PropsType, StateType> {
|
|||
throw missingCaseError(warning);
|
||||
}
|
||||
}
|
||||
|
||||
private getActions(): PropsActionsType {
|
||||
const unsafe = pick(this.props, [
|
||||
'acknowledgeGroupMemberNameCollisions',
|
||||
'clearChangedMessages',
|
||||
'clearInvitedConversationsForNewlyCreatedGroup',
|
||||
'closeContactSpoofingReview',
|
||||
'setLoadCountdownStart',
|
||||
'setIsNearBottom',
|
||||
'reviewGroupMemberNameCollision',
|
||||
'reviewMessageRequestNameCollision',
|
||||
'learnMoreAboutDeliveryIssue',
|
||||
'loadAndScroll',
|
||||
'loadOlderMessages',
|
||||
'loadNewerMessages',
|
||||
'loadNewestMessages',
|
||||
'markMessageRead',
|
||||
'markViewed',
|
||||
'onBlock',
|
||||
'onBlockAndReportSpam',
|
||||
'onDelete',
|
||||
'onUnblock',
|
||||
'removeMember',
|
||||
'selectMessage',
|
||||
'clearSelectedMessage',
|
||||
'unblurAvatar',
|
||||
'updateSharedGroups',
|
||||
|
||||
'doubleCheckMissingQuoteReference',
|
||||
'onHeightChange',
|
||||
'checkForAccount',
|
||||
'reactToMessage',
|
||||
'replyToMessage',
|
||||
'retrySend',
|
||||
'showForwardMessageModal',
|
||||
'deleteMessage',
|
||||
'deleteMessageForEveryone',
|
||||
'showMessageDetail',
|
||||
'openConversation',
|
||||
'showContactDetail',
|
||||
'showContactModal',
|
||||
'kickOffAttachmentDownload',
|
||||
'markAttachmentAsCorrupted',
|
||||
'showVisualAttachment',
|
||||
'downloadAttachment',
|
||||
'displayTapToViewMessage',
|
||||
'openLink',
|
||||
'scrollToQuotedMessage',
|
||||
'showExpiredIncomingTapToViewToast',
|
||||
'showExpiredOutgoingTapToViewToast',
|
||||
|
||||
'showIdentity',
|
||||
|
||||
'downloadNewVersion',
|
||||
|
||||
'contactSupport',
|
||||
]);
|
||||
|
||||
const safe: AssertProps<PropsActionsType, typeof unsafe> = unsafe;
|
||||
|
||||
return safe;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ import { StateType as RootStateType } from '../reducer';
|
|||
import { AttachmentType } from '../../types/Attachment';
|
||||
import { MessageAttributesType } from '../../model-types.d';
|
||||
import { LinkPreviewWithDomain } from '../../types/LinkPreview';
|
||||
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
||||
import {
|
||||
REMOVE_PREVIEW as REMOVE_LINK_PREVIEW,
|
||||
RemoveLinkPreviewActionType,
|
||||
} from './linkPreviews';
|
||||
|
||||
// State
|
||||
|
||||
|
@ -58,6 +63,7 @@ type ComposerActionType =
|
|||
| ResetComposerActionType
|
||||
| SetHighQualitySettingActionType
|
||||
| SetLinkPreviewResultActionType
|
||||
| RemoveLinkPreviewActionType
|
||||
| SetQuotedMessageActionType;
|
||||
|
||||
// Action Creators
|
||||
|
@ -176,5 +182,12 @@ export function reducer(
|
|||
};
|
||||
}
|
||||
|
||||
if (action.type === REMOVE_LINK_PREVIEW) {
|
||||
return assignWithNoUnnecessaryAllocation(state, {
|
||||
linkPreviewLoading: false,
|
||||
linkPreviewResult: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { LinkPreviewType } from '../../types/message/LinkPreviews';
|
||||
import { assignWithNoUnnecessaryAllocation } from '../../util/assignWithNoUnnecessaryAllocation';
|
||||
|
||||
// State
|
||||
|
||||
|
@ -12,14 +13,14 @@ export type LinkPreviewsStateType = {
|
|||
// Actions
|
||||
|
||||
const ADD_PREVIEW = 'linkPreviews/ADD_PREVIEW';
|
||||
const REMOVE_PREVIEW = 'linkPreviews/REMOVE_PREVIEW';
|
||||
export const REMOVE_PREVIEW = 'linkPreviews/REMOVE_PREVIEW';
|
||||
|
||||
type AddLinkPreviewActionType = {
|
||||
type: 'linkPreviews/ADD_PREVIEW';
|
||||
payload: LinkPreviewType;
|
||||
};
|
||||
|
||||
type RemoveLinkPreviewActionType = {
|
||||
export type RemoveLinkPreviewActionType = {
|
||||
type: 'linkPreviews/REMOVE_PREVIEW';
|
||||
};
|
||||
|
||||
|
@ -68,9 +69,9 @@ export function reducer(
|
|||
}
|
||||
|
||||
if (action.type === REMOVE_PREVIEW) {
|
||||
return {
|
||||
return assignWithNoUnnecessaryAllocation(state, {
|
||||
linkPreview: undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -4137,12 +4137,12 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
URL.revokeObjectURL(item.url);
|
||||
}
|
||||
});
|
||||
window.reduxActions.linkPreviews.removeLinkPreview();
|
||||
this.preview = null;
|
||||
this.currentlyMatchedLink = null;
|
||||
this.linkPreviewAbortController?.abort();
|
||||
this.linkPreviewAbortController = null;
|
||||
this.renderLinkPreview();
|
||||
|
||||
window.reduxActions.linkPreviews.removeLinkPreview();
|
||||
},
|
||||
|
||||
async getStickerPackPreview(
|
||||
|
|
Loading…
Add table
Reference in a new issue