diff --git a/Changelog.md b/Changelog.md index ada7a81a9..41ea41ac5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,7 @@ * Move non-model federation stuff into lib/ [#4363](https://github.com/diaspora/diaspora/pull/4363) * Build a color palette to uniform color usage [#4437](https://github.com/diaspora/diaspora/pull/4437) [#4469](https://github.com/diaspora/diaspora/pull/4469) [#4479](https://github.com/diaspora/diaspora/pull/4479) * Rename bitcoin_wallet_id setting to bitcoin_address [#4485](https://github.com/diaspora/diaspora/pull/4485) +* Batch insert posts into stream collection for a small speedup [#4341](https://github.com/diaspora/diaspora/pull/4351) ## Bug fixes * Highlight down arrow at the user menu on hover [#4441](https://github.com/diaspora/diaspora/pull/4441) diff --git a/app/assets/javascripts/app/models/stream.js b/app/assets/javascripts/app/models/stream.js index e642171e0..2af816384 100644 --- a/app/assets/javascripts/app/models/stream.js +++ b/app/assets/javascripts/app/models/stream.js @@ -54,10 +54,25 @@ app.models.Stream = Backbone.Collection.extend({ return this.basePath().match(/activity/) ? "interactedAt" : "createdAt" }, + /* This function is for adding a large number of posts one by one. + * Mainly used by backbone when loading posts from the server + * + * After adding the posts, you have to trigger "fetched" on the + * stream for the changes to take effect in the infinite stream view + */ add : function(models){ this.items.add(models) }, + /* This function is for adding a single post. It immediately triggers + * "fetched" on the stream, so the infinite stream view updates + * automatically. + */ + addNow : function(models){ + this.add(models); + this.trigger("fetched"); + }, + preloadOrFetch : function(){ //hai, plz test me THNX return $.when(app.hasPreload("stream") ? this.preload() : this.fetch()) }, diff --git a/app/assets/javascripts/app/views/infinite_stream_view.js b/app/assets/javascripts/app/views/infinite_stream_view.js index 8e2ff0b22..06963672b 100644 --- a/app/assets/javascripts/app/views/infinite_stream_view.js +++ b/app/assets/javascripts/app/views/infinite_stream_view.js @@ -8,11 +8,13 @@ app.views.InfScroll = app.views.Base.extend({ setupInfiniteScroll : function() { - this.postViews = this.postViews || [] + this.postViews = this.postViews || []; + this.appendedPosts = []; + this.prependedPosts = []; - this.bind("loadMore", this.fetchAndshowLoader, this) - this.stream.bind("fetched", this.hideLoader, this) - this.stream.bind("allItemsLoaded", this.unbindInfScroll, this) + this.bind("loadMore", this.fetchAndshowLoader, this); + this.stream.bind("fetched", this.finishedLoading, this); + this.stream.bind("allItemsLoaded", this.unbindInfScroll, this); this.collection.bind("add", this.addPostView, this); @@ -26,13 +28,21 @@ app.views.InfScroll = app.views.Base.extend({ createPostView : function(post){ var postView = new this.postClass({ model: post, stream: this.stream }); - this.postViews.push(postView) - return postView + if (this.collection.at(0).id == post.id) { + this.postViews.unshift(postView); + } else { + this.postViews.push(postView); + } + return postView; }, addPostView : function(post) { - var placeInStream = (this.collection.at(0).id == post.id) ? "prepend" : "append"; - this.$el[placeInStream](this.createPostView(post).render().el); + var el = this.createPostView(post).render().el; + if (this.collection.at(0).id == post.id) { + this.prependedPosts.unshift(el); + } else { + this.appendedPosts.push(el); + } }, unbindInfScroll : function() { @@ -44,24 +54,39 @@ app.views.InfScroll = app.views.Base.extend({ }, renderInitialPosts : function(){ - this.$el.empty() + this.$el.empty(); + var els = []; this.stream.items.each(_.bind(function(post){ - this.$el.append(this.createPostView(post).render().el); + els.push(this.createPostView(post).render().el); }, this)) + this.$el.append(els); }, fetchAndshowLoader : function(){ if(this.stream.isFetching()) { return false } - this.stream.fetch() - this.showLoader() + this.stream.fetch(); + this.showLoader(); }, showLoader: function(){ $("#paginate .loader").removeClass("hidden") }, + finishedAdding: function() { + var el = $(''); + this.$el.prepend(this.prependedPosts); + this.$el.append(this.appendedPosts); + this.appendedPosts = []; + this.prependedPosts = []; + }, + + finishedLoading: function() { + this.finishedAdding(); + this.hideLoader(); + }, + hideLoader: function() { - $("#paginate .loader").addClass("hidden") + $("#paginate .loader").addClass("hidden"); }, infScroll : function() { diff --git a/app/assets/javascripts/app/views/publisher_view.js b/app/assets/javascripts/app/views/publisher_view.js index 2e7488bc1..85a3af762 100644 --- a/app/assets/javascripts/app/views/publisher_view.js +++ b/app/assets/javascripts/app/views/publisher_view.js @@ -104,7 +104,7 @@ app.views.Publisher = Backbone.View.extend(_.extend( $(app.publisher.el).trigger('ajax:success'); } if(app.stream) { - app.stream.items.add(statusMessage.toJSON()); + app.stream.addNow(statusMessage.toJSON()); } } }); @@ -194,7 +194,7 @@ app.views.Publisher = Backbone.View.extend(_.extend( if(app.stream) { this.removePostPreview(); - app.stream.items.add(previewMessage); + app.stream.addNow(previewMessage); this.recentPreview=previewMessage; this.modifyPostPreview($('.stream_element:first',$('.stream_container'))); }