Throttle re-renders for rapidly-updating messages

This commit is contained in:
trevor-signal 2023-11-01 12:49:58 -04:00 committed by GitHub
parent 9206b9984b
commit 0da867a0ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2,6 +2,8 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';
import { throttle } from 'lodash';
import LRU from 'lru-cache';
import type { MessageAttributesType } from '../model-types.d'; import type { MessageAttributesType } from '../model-types.d';
import type { MessageModel } from '../models/messages'; import type { MessageModel } from '../models/messages';
import * as Errors from '../types/errors'; import * as Errors from '../types/errors';
@ -17,6 +19,7 @@ import { softAssert, strictAssert } from '../util/assert';
import { isStory } from '../messages/helpers'; import { isStory } from '../messages/helpers';
import { getStoryDataFromMessageAttributes } from './storyLoader'; import { getStoryDataFromMessageAttributes } from './storyLoader';
const MAX_THROTTLED_REDUX_UPDATERS = 200;
export class MessageCache { export class MessageCache {
private state = { private state = {
messages: new Map<string, MessageAttributesType>(), messages: new Map<string, MessageAttributesType>(),
@ -198,10 +201,42 @@ export class MessageCache {
this.markModelStale(nextMessageAttributes); this.markModelStale(nextMessageAttributes);
if (window.reduxActions) { this.throttledUpdateRedux(nextMessageAttributes);
if (isStory(nextMessageAttributes)) {
if (skipSaveToDatabase) {
return;
}
drop(
window.Signal.Data.saveMessage(messageAttributes, {
ourAci: window.textsecure.storage.user.getCheckedAci(),
})
);
}
private throttledReduxUpdaters = new LRU<string, typeof this.updateRedux>({
max: MAX_THROTTLED_REDUX_UPDATERS,
});
private throttledUpdateRedux(attributes: MessageAttributesType) {
let updater = this.throttledReduxUpdaters.get(attributes.id);
if (!updater) {
updater = throttle(this.updateRedux.bind(this), 200, {
leading: true,
trailing: true,
});
this.throttledReduxUpdaters.set(attributes.id, updater);
}
updater(attributes);
}
private updateRedux(attributes: MessageAttributesType) {
if (!window.reduxActions) {
return;
}
if (isStory(attributes)) {
const storyData = getStoryDataFromMessageAttributes({ const storyData = getStoryDataFromMessageAttributes({
...nextMessageAttributes, ...attributes,
}); });
if (!storyData) { if (!storyData) {
@ -215,19 +250,9 @@ export class MessageCache {
} }
window.reduxActions.conversations.messageChanged( window.reduxActions.conversations.messageChanged(
messageId, attributes.id,
nextMessageAttributes.conversationId, attributes.conversationId,
nextMessageAttributes attributes
);
}
if (skipSaveToDatabase) {
return;
}
drop(
window.Signal.Data.saveMessage(messageAttributes, {
ourAci: window.textsecure.storage.user.getCheckedAci(),
})
); );
} }