Throttle re-renders for rapidly-updating messages
This commit is contained in:
parent
9206b9984b
commit
0da867a0ef
1 changed files with 47 additions and 22 deletions
|
@ -2,6 +2,8 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { throttle } from 'lodash';
|
||||
import LRU from 'lru-cache';
|
||||
import type { MessageAttributesType } from '../model-types.d';
|
||||
import type { MessageModel } from '../models/messages';
|
||||
import * as Errors from '../types/errors';
|
||||
|
@ -17,6 +19,7 @@ import { softAssert, strictAssert } from '../util/assert';
|
|||
import { isStory } from '../messages/helpers';
|
||||
import { getStoryDataFromMessageAttributes } from './storyLoader';
|
||||
|
||||
const MAX_THROTTLED_REDUX_UPDATERS = 200;
|
||||
export class MessageCache {
|
||||
private state = {
|
||||
messages: new Map<string, MessageAttributesType>(),
|
||||
|
@ -198,28 +201,7 @@ export class MessageCache {
|
|||
|
||||
this.markModelStale(nextMessageAttributes);
|
||||
|
||||
if (window.reduxActions) {
|
||||
if (isStory(nextMessageAttributes)) {
|
||||
const storyData = getStoryDataFromMessageAttributes({
|
||||
...nextMessageAttributes,
|
||||
});
|
||||
|
||||
if (!storyData) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.reduxActions.stories.storyChanged(storyData);
|
||||
|
||||
// We don't want messageChanged to run
|
||||
return;
|
||||
}
|
||||
|
||||
window.reduxActions.conversations.messageChanged(
|
||||
messageId,
|
||||
nextMessageAttributes.conversationId,
|
||||
nextMessageAttributes
|
||||
);
|
||||
}
|
||||
this.throttledUpdateRedux(nextMessageAttributes);
|
||||
|
||||
if (skipSaveToDatabase) {
|
||||
return;
|
||||
|
@ -231,6 +213,49 @@ export class MessageCache {
|
|||
);
|
||||
}
|
||||
|
||||
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({
|
||||
...attributes,
|
||||
});
|
||||
|
||||
if (!storyData) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.reduxActions.stories.storyChanged(storyData);
|
||||
|
||||
// We don't want messageChanged to run
|
||||
return;
|
||||
}
|
||||
|
||||
window.reduxActions.conversations.messageChanged(
|
||||
attributes.id,
|
||||
attributes.conversationId,
|
||||
attributes
|
||||
);
|
||||
}
|
||||
|
||||
// When you already have the message attributes from the db and want to
|
||||
// ensure that they're added to the cache. The latest attributes from cache
|
||||
// are returned if they exist, if not the attributes passed in are returned.
|
||||
|
|
Loading…
Add table
Reference in a new issue