[Perf] Message: Clone appendix instead of parsing HTML

This commit is contained in:
Alexander Zinchuk 2023-07-20 15:58:19 +02:00
parent 5ea7919e92
commit 573649a495

View File

@ -1,6 +1,12 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, useCallback, useEffect, useMemo, useRef, useState, memo,
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
import type { import type {
@ -96,11 +102,7 @@ import {
ROUND_VIDEO_DIMENSIONS_PX, ROUND_VIDEO_DIMENSIONS_PX,
} from '../../common/helpers/mediaDimensions'; } from '../../common/helpers/mediaDimensions';
import { buildContentClassName } from './helpers/buildContentClassName'; import { buildContentClassName } from './helpers/buildContentClassName';
import { import { calculateMediaDimensions, getMinMediaWidth, MIN_MEDIA_WIDTH_WITH_TEXT } from './helpers/mediaDimensions';
calculateMediaDimensions,
getMinMediaWidth,
MIN_MEDIA_WIDTH_WITH_TEXT,
} from './helpers/mediaDimensions';
import { calculateAlbumLayout } from './helpers/calculateAlbumLayout'; import { calculateAlbumLayout } from './helpers/calculateAlbumLayout';
import renderText from '../../common/helpers/renderText'; import renderText from '../../common/helpers/renderText';
import { getServerTime } from '../../../util/serverTime'; import { getServerTime } from '../../../util/serverTime';
@ -280,6 +282,9 @@ const BOTTOM_FOCUS_SCROLL_THRESHOLD = 5;
const THROTTLE_MS = 300; const THROTTLE_MS = 300;
const RESIZE_ANIMATION_DURATION = 400; const RESIZE_ANIMATION_DURATION = 400;
let appendixOwnCloned: SVGElement;
let appendixNotOwnCloned: SVGElement;
const Message: FC<OwnProps & StateProps> = ({ const Message: FC<OwnProps & StateProps> = ({
message, message,
chatUsernames, chatUsernames,
@ -377,6 +382,8 @@ const Message: FC<OwnProps & StateProps> = ({
const bottomMarkerRef = useRef<HTMLDivElement>(null); const bottomMarkerRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const quickReactionRef = useRef<HTMLDivElement>(null); const quickReactionRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null
const appendixRef = useRef<HTMLDivElement>(null);
const messageHeightRef = useRef(0); const messageHeightRef = useRef(0);
@ -708,6 +715,30 @@ const Message: FC<OwnProps & StateProps> = ({
} }
}, [hasUnreadReaction, messageId, animateUnreadReaction]); }, [hasUnreadReaction, messageId, animateUnreadReaction]);
useLayoutEffect(() => {
if (!withAppendix) return;
const appendixEl = appendixRef.current!;
const cloned = isOwn ? appendixOwnCloned : appendixNotOwnCloned;
// eslint-disable-next-line no-underscore-dangle
const html = isOwn ? APPENDIX_OWN.__html : APPENDIX_NOT_OWN.__html;
let nextCloned: SVGElement;
if (cloned) {
nextCloned = cloned.cloneNode(true) as SVGElement;
appendixEl.appendChild(cloned);
} else {
appendixEl.innerHTML = html;
nextCloned = appendixEl.firstChild!.cloneNode(true) as SVGElement;
}
if (isOwn) {
appendixOwnCloned = nextCloned;
} else {
appendixNotOwnCloned = nextCloned;
}
}, [isOwn, withAppendix]);
let style = ''; let style = '';
let calculatedWidth; let calculatedWidth;
let reactionsMaxWidth; let reactionsMaxWidth;
@ -1282,7 +1313,7 @@ const Message: FC<OwnProps & StateProps> = ({
) : undefined} ) : undefined}
{withCommentButton && <CommentButton threadInfo={repliesThreadInfo!} disabled={noComments} />} {withCommentButton && <CommentButton threadInfo={repliesThreadInfo!} disabled={noComments} />}
{withAppendix && ( {withAppendix && (
<div className="svg-appendix" dangerouslySetInnerHTML={isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN} /> <div ref={appendixRef} className="svg-appendix" />
)} )}
{withQuickReactionButton && quickReactionPosition === 'in-content' && renderQuickReactionButton()} {withQuickReactionButton && quickReactionPosition === 'in-content' && renderQuickReactionButton()}
</div> </div>