From a1ce2fa2eff7c49cc58ecc3b041c80fc24ec61f8 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Thu, 7 May 2015 09:19:57 +0930 Subject: [PATCH] Prevent expensive redrawing in the discussion list --- js/forum/src/components/discussion-list.js | 21 +++++++++++++++++++-- js/forum/src/components/index-page.js | 5 +++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/js/forum/src/components/discussion-list.js b/js/forum/src/components/discussion-list.js index 14eca9046..2f176b83b 100644 --- a/js/forum/src/components/discussion-list.js +++ b/js/forum/src/components/discussion-list.js @@ -8,6 +8,7 @@ import ActionButton from 'flarum/components/action-button'; import DropdownButton from 'flarum/components/dropdown-button'; import LoadingIndicator from 'flarum/components/loading-indicator'; import TerminalPost from 'flarum/components/terminal-post'; +import SubtreeRetainer from 'flarum/utils/subtree-retainer'; export default class DiscussionList extends Component { constructor(props) { @@ -17,11 +18,25 @@ export default class DiscussionList extends Component { this.moreResults = m.prop(false); this.discussions = m.prop([]); + this.willRedraw(); this.refresh(); app.session.on('loggedIn', this.loggedInHandler = this.refresh.bind(this)) } + willRedraw() { + this.subtrees = []; + this.addSubtrees(this.discussions()); + } + + addSubtrees(discussions) { + discussions.forEach(discussion => { + this.subtrees[discussion.id()] = new SubtreeRetainer( + () => discussion.freshness + ) + }); + } + params() { var params = {}; for (var i in this.props.params) { @@ -75,6 +90,7 @@ export default class DiscussionList extends Component { parseResults(results) { m.startComputation(); this.loading(false); + this.addSubtrees(results); [].push.apply(this.discussions(), results); this.moreResults(!!results.payload.links.next); m.endComputation(); @@ -109,7 +125,8 @@ export default class DiscussionList extends Component { var discussionRoute = app.route('discussion', { id: discussion.id(), slug: discussion.slug() }); var active = m.route().substr(0, discussionRoute.length) === discussionRoute; - return m('li.discussion-summary'+(isUnread ? '.unread' : '')+(active ? '.active' : ''), {key: discussion.id()}, [ + var subtree = this.subtrees[discussion.id()]; + return m('li.discussion-summary'+(isUnread ? '.unread' : '')+(active ? '.active' : ''), {key: discussion.id()}, subtree.retain() || m('div', [ controls.length ? DropdownButton.component({ items: controls, className: 'contextual-controls', @@ -135,7 +152,7 @@ export default class DiscussionList extends Component { abbreviateNumber(discussion[displayUnread ? 'unreadCount' : 'repliesCount']()), m('span.label', displayUnread ? 'unread' : 'replies') ]) - ]) + ])) }) ]), this.loading() diff --git a/js/forum/src/components/index-page.js b/js/forum/src/components/index-page.js index c04915827..4290e06cd 100644 --- a/js/forum/src/components/index-page.js +++ b/js/forum/src/components/index-page.js @@ -21,6 +21,7 @@ export default class IndexPage extends Component { var params = this.params(); if (app.cache.discussionList) { + app.cache.discussionList.willRedraw(); Object.keys(params).some(key => { if (app.cache.discussionList.props.params[key] !== params[key]) { app.cache.discussionList = null; @@ -37,6 +38,10 @@ export default class IndexPage extends Component { app.composer.minimize(); } + onunload() { + app.cache.discussionList.willRedraw(); + } + /** Params that stick between filter changes */