所以我的 draft-js 编辑器变得非常慢(hacky)我插入的内容越多(在大约 20 个装饰器替换之后)。我猜这种行为是由于装饰器使用正则表达式检查整个编辑器内容,并在每次状态更改时用表情符号组件替换匹配项。我还为正则表达式找到的每个匹配项创建实体,我通过使用编辑器状态作为 Prop 装饰组件来做到这一点。有没有办法让它更快? 这是我的装饰器:
{
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
的一部分 – 在内容保存和最终呈现之前。 - 使用仅基于实体的装饰器策略,例如:
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 .您将能够准确判断出在击键过程中渲染哪些内容需要时间,然后追踪问题。
关于javascript - 由于装饰器过多,随着内容的增加,Draft js Editor 变慢了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52240569/