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
|
// 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,28 +201,7 @@ export class MessageCache {
|
||||||
|
|
||||||
this.markModelStale(nextMessageAttributes);
|
this.markModelStale(nextMessageAttributes);
|
||||||
|
|
||||||
if (window.reduxActions) {
|
this.throttledUpdateRedux(nextMessageAttributes);
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipSaveToDatabase) {
|
if (skipSaveToDatabase) {
|
||||||
return;
|
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
|
// 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
|
// 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.
|
// are returned if they exist, if not the attributes passed in are returned.
|
||||||
|
|
Loading…
Add table
Reference in a new issue