在~2K记录上反应速度慢

时间:2017-06-01 10:15:32

标签: javascript performance reactjs

我有一个小的ReactJS聊天应用程序,消息存储在全局数组client.chat中作为对象与propery txt,其中包含文本。问题是性能,对于~2K消息,我必须在每个新消息之后等待几秒钟,即使网络被注释掉,所以它只是简单地重新呈现HTML。我试图在AngularJS中实现相同的应用程序,它没有任何延迟。那么瓶颈在哪里?

var client = {user: {}, chat: []};
class App extends React.Component {
    constructor() {
        super();
        this.socketio = ...
        // here i perform some network initialization and 
        // call client.updateChat when data has arrived over network
        client.updateChat = function () {
            me.setState({chat: client.chat.concat([]).reverse()});
        };
        client.addMessage = function (msg) {
            me.setState(prevState=>({
                chat:[msg].concat(prevState.chat)
            }));
        };
        this.updateState = this.updateState.bind(this);
        this.state = {chat: []};
    }
    updateState(e) {
        this.setState({data: e.target.value});
    }
    render() {
        return (
            <span>
                <Input socketio={this.socketio} visitorId={this.visitorId}/>
                <table>
                        <Chat data={this.state.chat} socketio={this.socketio}>
                        </Chat>
                </table>
            </span>
        );
    }
}

这是输入组件,基本上代表输入框:

class Input extends React.Component {
    constructor() {
        super();
        this.state = {inputValue: ''};
        this.updateInputValue = this.updateInputValue.bind(this);
        this.handleKeyPress = this.handleKeyPress.bind(this);
        this.getFile = this.getFile.bind(this);
    }
    getFile(e) {/* attachment handling */  }    
    handleKeyPress(target) {
        if (target.charCode == 13) {
            if (this.state.inputValue.length == 0) return;
            var inputValue = this.state.inputValue;
            this.setState({inputValue: ''});
            var ts = Date.now();
            var elem = {
                txt: inputValue, file: null, ts: ts, from: 'support', tsStr: formateDate(ts), name: client.user.name, attachmentName: null, dataType: null
            };
            client.addMessage(elem);
        }
    }
    updateInputValue(evt) {
        this.setState({inputValue: evt.target.value});
    }
    render() {
        return (<div className="input">
            <table width="100%">
                <tbody>
                <tr>
                    <td>
                        <label className="customUpload btnUpload btnM">
                            <span><img width="15px" src="images/attach.png"/></span>
                            <input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>
                        </label>
                    </td>
                    <td>
                        <input value={this.state.inputValue}
                               onKeyPress={this.handleKeyPress}
                               onChange={this.updateInputValue}
                               className="textInput"/>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>);
    }
}

这是聊天组件,代表聊天本身。

class Chat extends React.Component {
    constructor() {super();}
    render() {
        return (
            <tbody>
            {this.props.data.map((p, i) => <Msg socketio={this.props.socketio} key={i} data={p}/>)}
            </tbody>
        );
    }
}

这是一条消息:

class Msg extends React.Component {
    constructor(props) {
        super(props);
    }
    shouldComponentUpdate(nextProps, nextState) {
        if (this.props.data.txt == nextProps.data.txt) {
            return false;
        }
        return true;
    }

    render() {
        var words = (this.props.data.txt || "").split(" ");
        // this piece of code splits this.props.data.txt by spaces
        // and converts it to array of words warr
        // ...
        return (
            <tr className={this.trStyle()}>
                <td>
                    <div className="msg">
                        {
                            warr.map((word, k) => <Word socketio={this.props.socketio} key={k} data={word.txt}/>)
                        }
                    </div>
                </td>
            </tr>
        );
    }
}

此类用于消息中的单个单词。如果单词太长,函数shortened()将返回缩写版本。

class Word extends React.Component {
    shortened() { //....
    render() {
        return (
            <span className={this.wordClass()} onClick={this.click}>{this.shortened()} </span>
        );
    }
}

我已经实现了使用concat()而不是push()添加新消息,遵循Facebook的性能指南,并且还实现了shouldComponentUpdate以避免txt.split(&#34;&#34;)重新计算。但它并没有给我带来任何性能提升。任何人都可以给我一些建议或想法吗?

1 个答案:

答案 0 :(得分:0)

您绑定的响应对象的大小是多少?我们有类似的问题,我们之前有120kb大小的json对象,我们绑定了反应,但后来优化了json对象并将json对象分成两部分。 1. Pageload JSON对象 - 它具有包含所有字段和值的完整Json对象(默认) 2. Delta对象 - 它只改变了对象字段,它是我们用于在React中合并的值