所以我的draft-js编辑器变得非常慢(hacky)我插入的内容越多(在大约20个装饰器替换之后)。我猜测这种行为是由于装饰器使用正则表达式检查整个编辑器内容,并在每次状态更改时用emoji组件替换匹配。我也为正则表达式找到的每个匹配创建实体,我通过用编辑器状态作为道具来装饰组件来实现。有没有办法让它更快?这是我的装饰者:
{
strategy: emojiStrategy,
component: decorateComponentWithProps(RenderEmoji, {
getEditorState: this.getEditorState,
setEditorState: this.onChange
})
}
这是我的表情符号策略:
function emojiRegexF(regex, contentBlock, callback, contentState) {
const text = contentBlock.getText();
let matchArr, start;
while ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
callback(start, start + matchArr[0].length);
}
}
function emojiStrategy(contentBlock, callback, contentState) {
emojiRegexF(EMOJI_REGEX, contentBlock, callback, contentState);
}
这是我的RenderEmoji组件:
const RenderEmoji = props => {
const contentBlock = props.children[0].props.block;
const emojiKey = contentBlock.getEntityAt(props.children[0].props.start);
const emojiShortName = props.decoratedText;
if (!emojiKey) {
setEntity(props, emojiShortName);
}
return (
<Emoji emoji={emojiShortName} set="emojione" size={24}>
{props.children}
</Emoji>
);
};
这是我的setEntity函数,用于设置匹配的实体:
function setEntity(props, emojiShortName) {
const editorState = props.getEditorState();
const contentstate = editorState.getCurrentContent();
const contentStateWithEntity = contentstate.createEntity(
"emoji",
"IMMUTABLE",
{
emojiUnicode: emojiShortName
}
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const oldSelectionState = editorState.getSelection();
const selectionState = oldSelectionState.merge({
focusOffset: props.children[0].props.start + props.decoratedText.length,
anchorOffset: props.children[0].props.start
});
const newContentState = Modifier.applyEntity(
contentstate,
selectionState,
entityKey
);
const withBlank = Modifier.replaceText(
newContentState,
selectionState,
emojiShortName + " ",
null,
entityKey
);
const newEditorState = EditorState.push(
editorState,
withBlank,
"apply-entity"
);
props.setEditorState(newEditorState);
}
我能以任何方式优化这个吗?谢谢
我不确定这是否会成为任何真正的性能问题的根源,但有两件事看起来很有趣:
setEntity
)。渲染函数should be pure。我想你会做这种类型的处理,因为可以通过复制粘贴或某种本机表情符号选择器插入表情符号。更好的方法是:
setEntity
逻辑作为onChange
的一部分插入emojis的实体。const emojiStrategy = (contentBlock, callback, contentState) => {
contentBlock.findEntityRanges(character => {
const entityKey = character.getEntity();
return (
entityKey !== null &&
contentState.getEntity(entityKey).getType() === 'emoji'
);
}, callback);
};
然后,您的装饰器组件将不需要在渲染期间更新编辑器状态。您也可能不再需要使用decorateComponentWithProps
了。
现在回到表演 - 最好的方式让你知道如何改进它是profile your app。您将能够确切地告诉在击键过程中需要花费多少时间进行渲染,然后追踪问题。