我有小ReactJS聊天應用,消息被存儲全局陣列內client.chat與屬性格式TXT,其中包含的文本對象。問題是性能比較,對〜2K的消息我每一個新的消息後,等待幾秒鐘,即使網絡已被註釋掉,因此它只是rerendeing HTML的。我試圖在AngularJS中實現相同的應用程序,它沒有任何延遲。那麼瓶頸在哪裏呢?慢速反應上〜2K記錄性能比較
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>
);
}
}
此類是一個消息內的單個字。如果一個單詞太長,函數short()會返回縮寫版本。
class Word extends React.Component {
shortened() { //....
render() {
return (
<span className={this.wordClass()} onClick={this.click}>{this.shortened()} </span>
);
}
}
我已經實現了使用CONCAT增加新的消息(),而不是推(),下面從Facebook性能比較指南和還實施shouldComponentUpdate避免txt.split(」「)重新計算。但它沒有給我任何性能提升。任何人都可以給我更多的建議或想法嗎?