CompositionInput: Fix high CPU usage

This commit is contained in:
Ken Powers 2020-03-23 17:09:12 -04:00 committed by Scott Nonnenberg
parent a1270867ff
commit 17f212ffcf
3 changed files with 26 additions and 16 deletions

View file

@ -27,7 +27,7 @@ import {
search, search,
} from './emoji/lib'; } from './emoji/lib';
import { LocalizerType } from '../types/Util'; import { LocalizerType } from '../types/Util';
import { mergeRefs } from './_util'; import { createRefMerger } from './_util';
const MAX_LENGTH = 64 * 1024; const MAX_LENGTH = 64 * 1024;
const colonsRegex = /(?:^|\s):[a-z0-9-_+]+:?/gi; const colonsRegex = /(?:^|\s):[a-z0-9-_+]+:?/gi;
@ -237,6 +237,7 @@ export const CompositionInput = ({
const focusRef = React.useRef(false); const focusRef = React.useRef(false);
const editorStateRef = React.useRef<EditorState>(editorRenderState); const editorStateRef = React.useRef<EditorState>(editorRenderState);
const rootElRef = React.useRef<HTMLDivElement>(); const rootElRef = React.useRef<HTMLDivElement>();
const rootElRefMerger = React.useMemo(createRefMerger, []);
// This function sets editorState and also keeps a reference to the newly set // This function sets editorState and also keeps a reference to the newly set
// state so we can reference the state in effects and callbacks without // state so we can reference the state in effects and callbacks without
@ -757,7 +758,7 @@ export const CompositionInput = ({
{({ measureRef }) => ( {({ measureRef }) => (
<div <div
className="module-composition-input__input" className="module-composition-input__input"
ref={mergeRefs(popperRef, measureRef, rootElRef)} ref={rootElRefMerger(popperRef, measureRef, rootElRef)}
> >
<div <div
className={classNames( className={classNames(

View file

@ -2,20 +2,25 @@
import { Ref } from 'react'; import { Ref } from 'react';
import { isFunction } from 'lodash'; import { isFunction } from 'lodash';
import memoizee from 'memoizee';
export function cleanId(id: string): string { export function cleanId(id: string): string {
return id.replace(/[^\u0020-\u007e\u00a0-\u00ff]/g, '_'); return id.replace(/[^\u0020-\u007e\u00a0-\u00ff]/g, '_');
} }
export function mergeRefs<T>(...refs: Array<Ref<T>>) { export const createRefMerger = () =>
return (t: T) => { memoizee(
refs.forEach(r => { <T>(...refs: Array<Ref<T>>) => {
if (isFunction(r)) { return (t: T) => {
r(t); refs.forEach(r => {
} else if (r) { if (isFunction(r)) {
// @ts-ignore: React's typings for ref objects is annoying r(t);
r.current = t; } else if (r) {
} // @ts-ignore: React's typings for ref objects is annoying
}); r.current = t;
}; }
} });
};
},
{ length: false, max: 1 }
);

View file

@ -40,7 +40,7 @@ import { ContactType } from '../../types/Contact';
import { getIncrement } from '../../util/timer'; import { getIncrement } from '../../util/timer';
import { isFileDangerous } from '../../util/isFileDangerous'; import { isFileDangerous } from '../../util/isFileDangerous';
import { ColorType, LocalizerType } from '../../types/Util'; import { ColorType, LocalizerType } from '../../types/Util';
import { mergeRefs } from '../_util'; import { createRefMerger } from '../_util';
import { ContextMenu, ContextMenuTrigger, MenuItem } from 'react-contextmenu'; import { ContextMenu, ContextMenuTrigger, MenuItem } from 'react-contextmenu';
interface Trigger { interface Trigger {
@ -181,6 +181,7 @@ export class Message extends React.PureComponent<Props, State> {
public reactionsContainerRef: React.RefObject< public reactionsContainerRef: React.RefObject<
HTMLDivElement HTMLDivElement
> = React.createRef(); > = React.createRef();
public reactionsContainerRefMerger = createRefMerger();
public wideMl: MediaQueryList; public wideMl: MediaQueryList;
@ -1572,7 +1573,10 @@ export class Message extends React.PureComponent<Props, State> {
<Reference> <Reference>
{({ ref: popperRef }) => ( {({ ref: popperRef }) => (
<div <div
ref={mergeRefs(this.reactionsContainerRef, popperRef)} ref={this.reactionsContainerRefMerger(
this.reactionsContainerRef,
popperRef
)}
className={classNames( className={classNames(
'module-message__reactions', 'module-message__reactions',
outgoing outgoing