Javascript 由于有许多装饰器,所以随着内容的增加,Draft js Editor的速度会变慢

Javascript 由于有许多装饰器,所以随着内容的增加,Draft js Editor的速度会变慢,javascript,reactjs,draftjs,Javascript,Reactjs,Draftjs,因此,我插入的内容越多(大约替换了20个decorator之后),我的草稿js编辑器就变得非常慢(粗糙)。我猜这种行为是由于decorator使用regex检查整个编辑器内容,并在每次状态更改时用emoji组件替换匹配项。我还为regex查找的每个匹配项创建实体,我通过使用编辑器状态作为道具装饰组件来实现这一点。有没有办法让它更快? 这是我的装饰师: { strategy: emojiStrategy, component: deco

因此,我插入的内容越多(大约替换了20个decorator之后),我的草稿js编辑器就变得非常慢(粗糙)。我猜这种行为是由于decorator使用regex检查整个编辑器内容,并在每次状态更改时用emoji组件替换匹配项。我还为regex查找的每个匹配项创建实体,我通过使用编辑器状态作为道具装饰组件来实现这一点。有没有办法让它更快? 这是我的装饰师:

       {
            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);
}
以下是我的RenderoJi组件:

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
    )。渲染函数
我想你做这种类型的处理是因为表情符号可能是通过复制粘贴插入的,或者是通过某种本机表情符号选择器插入的。更好的方法是:

  • 在保存并最终呈现内容之前,使用
    setEntity
    逻辑将emojis的实体作为
    onChange
    的一部分插入
  • 使用仅基于实体的装饰器策略,例如:
  • const emojiStrategy=(contentBlock、回调、contentState)=>{
    contentBlock.findEntityRanges(字符=>{
    const entityKey=character.getEntity();
    返回(
    entityKey!==null&&
    contentState.getEntity(entityKey).getType()==='emoji'
    );
    },回调);
    };
    
    这样,装饰器组件就不需要在渲染期间更新编辑器状态。您也可能不再需要使用
    decorecomponentwithprops



    现在回到性能上来——对于您来说,确定如何提高性能的最佳方法是。您将能够准确地知道在击键期间渲染所需的时间,然后跟踪问题。

    谢谢,这似乎是一个可能的解决方案。还有一个问题,有没有办法使实体不可编辑(而不是不可变的)?就像我有这些装饰符,它们的短名称是props.children中的文本,所以当我在编辑器中使用左箭头返回时,我仍然可以更改表情文字的值,这会破坏实体并使装饰符发生更改。我想要的是,装饰师创建的表情图像被视为单个字符,用户不能像不可变实体那样编辑它,但也不能编辑它。希望这能让你sense@AliZeaiter这可能需要一个单独的问题而不是评论。我想我应该尝试用一个空格来替换表情符号,这样实体总是一个字符(就像原子块一样)。如果您使实体
    不可变
    ,我认为用户不可能更改字符。
    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);
    }