Avoid rerendering EventTiles when not necessary

Each individual eventtile isn't particularly expensive, but when you have 500
of them, they start adding up. Shuffle some of the stuff into MessagePanel, so
that we can shouldComponentUpdate EventTiles properly.
This commit is contained in:
Richard van der Hoff 2016-04-19 19:38:54 +01:00
parent 8bb13db7d4
commit 568e7aef8b
2 changed files with 94 additions and 23 deletions

View file

@ -19,6 +19,8 @@ var ReactDOM = require("react-dom");
var dis = require("../../dispatcher");
var sdk = require('../../index');
var MatrixClientPeg = require('../../MatrixClientPeg')
/* (almost) stateless UI component which builds the event tiles in the room timeline.
*/
module.exports = React.createClass({
@ -150,7 +152,7 @@ module.exports = React.createClass({
this.refs.scrollPanel.scrollToBottom();
}
},
/**
* Page up/down.
*
@ -335,13 +337,17 @@ module.exports = React.createClass({
// Local echos have a send "status".
var scrollToken = mxEv.status ? undefined : eventId;
var readReceipts = this._getReadReceiptsForEvent(mxEv);
ret.push(
<li key={eventId}
ref={this._collectEventNode.bind(this, eventId)}
data-scroll-token={scrollToken}>
<EventTile mxEvent={mxEv} continuation={continuation}
onWidgetLoad={this._onWidgetLoad}
last={last} isSelectedEvent={highlight} />
readReceipts={readReceipts}
eventSendStatus={mxEv.status}
last={last} isSelectedEvent={highlight}/>
</li>
);
@ -359,6 +365,30 @@ module.exports = React.createClass({
!== new Date(nextEventTs).toDateString());
},
// get a list of the userids whose read receipts should
// be shown next to this event
_getReadReceiptsForEvent: function(event) {
var myUserId = MatrixClientPeg.get().credentials.userId;
// get list of read receipts, sorted most recent first
var room = MatrixClientPeg.get().getRoom(event.getRoomId());
if (!room) {
// huh.
return null;
}
return room.getReceiptsForEvent(event).filter(function(r) {
return r.type === "m.read" && r.userId != myUserId;
}).sort(function(r1, r2) {
return r2.data.ts - r1.data.ts;
}).map(function(r) {
return room.getMember(r.userId);
}).filter(function(m) {
// check that the user is a known room member
return m;
});
},
_getReadMarkerTile: function(visible) {
var hr;
if (visible) {
@ -431,7 +461,7 @@ module.exports = React.createClass({
return (
<ScrollPanel ref="scrollPanel" className="mx_RoomView_messagePanel mx_fadable"
onScroll={ this.props.onScroll }
onScroll={ this.props.onScroll }
onResize={ this.onResize }
onFillRequest={ this.props.onFillRequest }
style={ style }