我有一个小的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;)重新计算。但它并没有给我带来任何性能提升。任何人都可以给我一些建议或想法吗?
答案 0 :(得分:0)
您绑定的响应对象的大小是多少?我们有类似的问题,我们之前有120kb大小的json对象,我们绑定了反应,但后来优化了json对象并将json对象分成两部分。 1. Pageload JSON对象 - 它具有包含所有字段和值的完整Json对象(默认) 2. Delta对象 - 它只改变了对象字段,它是我们用于在React中合并的值