FEATURE: higher slack ratio out of the box

I upped the slack ratio for a few reasons

1. We render ucloaked anyway on first render,
   so cloaking really is not saving much
2. On mobile you don't get JS events so you need
   a lot more slack to minimize white screens
3. Vast majority of memory is used by object model,
   if we want to tame it we need to remove posts from stream

ember cloaking now supports high slack ratios without going into a tail spin
This commit is contained in:
Sam 2014-06-10 15:04:34 +10:00
parent 2042ed02ec
commit 383f0290a4
4 changed files with 65 additions and 41 deletions

View File

@ -275,10 +275,6 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
return post.get('post_number') === 1 && post.get('topic.expandable_first_post'); return post.get('post_number') === 1 && post.get('topic.expandable_first_post');
}.property(), }.property(),
slackRatio: function() {
return Discourse.Capabilities.currentProp('slackRatio');
}.property(),
jumpTopDisabled: function() { jumpTopDisabled: function() {
return (this.get('progressPosition') < 2); return (this.get('progressPosition') < 2);
}.property('progressPosition'), }.property('progressPosition'),

View File

@ -5,29 +5,6 @@
@namespace Discourse @namespace Discourse
@module Discourse @module Discourse
**/ **/
Discourse.Capabilities = Ember.Object.extend({ Discourse.Capabilities = Ember.Object.extend({});
/**
How much slack we should allow with infinite scrolling.
@property slackRatio
**/
slackRatio: function() {
// Android is slow, so we use a really small slack
if (this.get('android')) { return 0.5; }
// Touch devices get more slack due to inertia
if (this.get('touch')) { return 1.5; }
var desktopSlack = parseFloat(Discourse.SiteSettings.desktop_post_slack_ratio,10);
desktopSlack = Math.max(desktopSlack,1);
// Higher resolution devices (likely laptops/desktops) should get more slack because they
// can handle the perf.
return this.get('highRes') ? desktopSlack : 0.75;
}.property('android', 'touch', 'highRes')
});
Discourse.Capabilities.reopenClass(Discourse.Singleton); Discourse.Capabilities.reopenClass(Discourse.Singleton);

View File

@ -82,7 +82,7 @@
idProperty="post_number" idProperty="post_number"
defaultHeight="200" defaultHeight="200"
content=postStream.posts content=postStream.posts
slackRatio=slackRatio slackRatio="15"
loadingHTML=controller.loadingHTML loadingHTML=controller.loadingHTML
preservesContext="true" preservesContext="true"
uncloakDefault="true" uncloakDefault="true"

View File

@ -83,19 +83,25 @@
findTopView: function(childViews, viewportTop, min, max) { findTopView: function(childViews, viewportTop, min, max) {
if (max < min) { return min; } if (max < min) { return min; }
var mid = Math.floor((min + max) / 2), var wrapperTop = this.get('wrapperTop')>>0;
// in case of not full-window scrolling
scrollOffset = this.get('wrapperTop') >> 0,
$view = childViews[mid].$(),
viewBottom = $view.position().top + scrollOffset + $view.height();
if (viewBottom > viewportTop) { while(max>min){
return this.findTopView(childViews, viewportTop, min, mid-1); var mid = Math.floor((min + max) / 2),
} else { // in case of not full-window scrolling
return this.findTopView(childViews, viewportTop, mid+1, max); $view = childViews[mid].$(),
viewBottom = $view.position().top + wrapperTop + $view.height();
if (viewBottom > viewportTop) {
max = mid-1;
} else {
min = mid+1;
}
} }
return min;
}, },
/** /**
Determine what views are onscreen and cloak/uncloak them as necessary. Determine what views are onscreen and cloak/uncloak them as necessary.
@ -107,8 +113,10 @@
var childViews = this.get('childViews'); var childViews = this.get('childViews');
if ((!childViews) || (childViews.length === 0)) { return; } if ((!childViews) || (childViews.length === 0)) { return; }
var toUncloak = [], var self = this,
toUncloak = [],
onscreen = [], onscreen = [],
onscreenCloaks = [],
// calculating viewport edges // calculating viewport edges
$w = $(window), $w = $(window),
windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ), windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ),
@ -148,6 +156,7 @@
if (viewBottom > windowTop && viewTop <= windowBottom) { if (viewBottom > windowTop && viewTop <= windowBottom) {
onscreen.push(view.get('content')); onscreen.push(view.get('content'));
onscreenCloaks.push(view);
} }
bottomView++; bottomView++;
@ -168,9 +177,22 @@
} }
var toCloak = childViews.slice(0, topView).concat(childViews.slice(bottomView+1)); var toCloak = childViews.slice(0, topView).concat(childViews.slice(bottomView+1));
Em.run.schedule('afterRender', function() {
toUncloak.forEach(function (v) { v.uncloak(); }); this._uncloak = toUncloak;
if(this._nextUncloak){
Em.run.cancel(this._nextUncloak);
this._nextUncloak = null;
}
Em.run.schedule('afterRender', this, function() {
onscreenCloaks.forEach(function (v) {
if(v && v.uncloak) {
v.uncloak();
}
});
toCloak.forEach(function (v) { v.cloak(); }); toCloak.forEach(function (v) { v.cloak(); });
if(self._nextUncloak){Em.run.cancel(self._nextUncloak)}
self._nextUncloak = Em.run.later(self, self.uncloakQueue,50);
}); });
for (var j=bottomView; j<childViews.length; j++) { for (var j=bottomView; j<childViews.length; j++) {
@ -185,6 +207,35 @@
}, },
uncloakQueue: function(){
var maxPerRun = 3, delay = 50, processed = 0, self = this;
if(this._uncloak){
while(processed < maxPerRun && this._uncloak.length>0){
var view = this._uncloak.shift();
if(view && view.uncloak && !view._containedView){
Em.run.schedule('afterRender', view, view.uncloak);
processed++;
}
}
if(this._uncloak.length === 0){
this._uncloak = null;
} else {
Em.run.schedule('afterRender', self, function(){
if(self._nextUncloak){
Em.run.cancel(self._nextUncloak);
}
self._nextUncloak = Em.run.next(self, function(){
if(self._nextUncloak){
Em.run.cancel(self._nextUncloak);
}
self._nextUncloak = Em.run.later(self,self.uncloakQueue,delay);
});
});
}
}
},
scrollTriggered: function() { scrollTriggered: function() {
Em.run.scheduleOnce('afterRender', this, 'scrolled'); Em.run.scheduleOnce('afterRender', this, 'scrolled');
}, },