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');
}.property(),
slackRatio: function() {
return Discourse.Capabilities.currentProp('slackRatio');
}.property(),
jumpTopDisabled: function() {
return (this.get('progressPosition') < 2);
}.property('progressPosition'),

View File

@ -5,29 +5,6 @@
@namespace Discourse
@module Discourse
**/
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 = Ember.Object.extend({});
Discourse.Capabilities.reopenClass(Discourse.Singleton);

View File

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

View File

@ -83,19 +83,25 @@
findTopView: function(childViews, viewportTop, min, max) {
if (max < min) { return min; }
var mid = Math.floor((min + max) / 2),
// in case of not full-window scrolling
scrollOffset = this.get('wrapperTop') >> 0,
$view = childViews[mid].$(),
viewBottom = $view.position().top + scrollOffset + $view.height();
var wrapperTop = this.get('wrapperTop')>>0;
if (viewBottom > viewportTop) {
return this.findTopView(childViews, viewportTop, min, mid-1);
} else {
return this.findTopView(childViews, viewportTop, mid+1, max);
while(max>min){
var mid = Math.floor((min + max) / 2),
// in case of not full-window scrolling
$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.
@ -107,8 +113,10 @@
var childViews = this.get('childViews');
if ((!childViews) || (childViews.length === 0)) { return; }
var toUncloak = [],
var self = this,
toUncloak = [],
onscreen = [],
onscreenCloaks = [],
// calculating viewport edges
$w = $(window),
windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ),
@ -148,6 +156,7 @@
if (viewBottom > windowTop && viewTop <= windowBottom) {
onscreen.push(view.get('content'));
onscreenCloaks.push(view);
}
bottomView++;
@ -168,9 +177,22 @@
}
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(); });
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++) {
@ -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() {
Em.run.scheduleOnce('afterRender', this, 'scrolled');
},