Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 16c2429

Browse files
committed
Cache the results of shouldShowEvent in MessagePanel
1 parent d1ac2c8 commit 16c2429

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

src/components/structures/MessagePanel.tsx

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -561,14 +561,38 @@ export default class MessagePanel extends React.Component<IProps, IState> {
561561
});
562562
};
563563

564-
private getNextEventInfo(arr: MatrixEvent[], i: number): { nextEvent: MatrixEvent; nextTile: MatrixEvent } {
564+
/**
565+
* Find the next event in the list, and the next visible event in the list.
566+
*
567+
* @param arr - the list of events to look in
568+
* @param shouldShow - which of these events should be shown (a cache of
569+
* calling this.shouldShowEvent(e) for each e in arr)
570+
* @param i - where in the list we are now
571+
*
572+
* @returns { nextEvent, nextTile }
573+
*
574+
* nextEvent is the last event in the supplied array.
575+
*
576+
* nextTile is the last event in the array that we will show a tile for. It
577+
* is used to to determine the 'last successful' flag when rendering the
578+
* tile.
579+
*/
580+
private getNextEventInfo(
581+
arr: MatrixEvent[],
582+
shouldShow: boolean[],
583+
i: number,
584+
): { nextEvent: MatrixEvent; nextTile: MatrixEvent } {
585+
// WARNING: this method is on a hot path.
586+
565587
const nextEvent = i < arr.length - 1 ? arr[i + 1] : null;
566588

567-
// The next event with tile is used to to determine the 'last successful' flag
568-
// when rendering the tile. The shouldShowEvent function is pretty quick at what
569-
// it does, so this should have no significant cost even when a room is used for
570-
// not-chat purposes.
571-
const nextTile = arr.slice(i + 1).find((e) => this.shouldShowEvent(e));
589+
let nextTile = null;
590+
for (let n = i + 1; n < arr.length; n++) {
591+
if (shouldShow[n]) {
592+
nextTile = arr[n];
593+
break;
594+
}
595+
}
572596

573597
return { nextEvent, nextTile };
574598
}
@@ -587,22 +611,21 @@ export default class MessagePanel extends React.Component<IProps, IState> {
587611
}
588612

589613
private getEventTiles(): ReactNode[] {
590-
let i;
591-
592614
// first figure out which is the last event in the list which we're
593615
// actually going to show; this allows us to behave slightly
594616
// differently for the last event in the list. (eg show timestamp)
595617
//
596618
// we also need to figure out which is the last event we show which isn't
597619
// a local echo, to manage the read-marker.
598-
let lastShownEvent;
620+
let lastShownEvent: MatrixEvent | undefined;
621+
const shouldShow = this.props.events.map((e) => this.shouldShowEvent(e));
599622

600623
let lastShownNonLocalEchoIndex = -1;
601-
for (i = this.props.events.length - 1; i >= 0; i--) {
602-
const mxEv = this.props.events[i];
603-
if (!this.shouldShowEvent(mxEv)) {
624+
for (let i = this.props.events.length - 1; i >= 0; i--) {
625+
if (!shouldShow[i]) {
604626
continue;
605627
}
628+
const mxEv = this.props.events[i];
606629

607630
if (lastShownEvent === undefined) {
608631
lastShownEvent = mxEv;
@@ -631,11 +654,12 @@ export default class MessagePanel extends React.Component<IProps, IState> {
631654

632655
let grouper: BaseGrouper = null;
633656

634-
for (i = 0; i < this.props.events.length; i++) {
657+
for (let i = 0; i < this.props.events.length; i++) {
635658
const mxEv = this.props.events[i];
659+
const shouldShowEv = shouldShow[i];
636660
const eventId = mxEv.getId();
637661
const last = mxEv === lastShownEvent;
638-
const { nextEvent, nextTile } = this.getNextEventInfo(this.props.events, i);
662+
const { nextEvent, nextTile } = this.getNextEventInfo(this.props.events, shouldShow, i);
639663

640664
if (grouper) {
641665
if (grouper.shouldGroup(mxEv)) {
@@ -658,7 +682,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
658682
}
659683

660684
if (!grouper) {
661-
if (this.shouldShowEvent(mxEv)) {
685+
if (shouldShowEv) {
662686
// make sure we unpack the array returned by getTilesForEvent,
663687
// otherwise React will auto-generate keys, and we will end up
664688
// replacing all the DOM elements every time we paginate.

0 commit comments

Comments
 (0)