Skip to content

Commit 7130060

Browse files
authored
Merge pull request #45 from nfl/issue/44
(refactor) throttle foldCheck instead of debounce
2 parents ee26b0e + 597b697 commit 7130060

File tree

5 files changed

+179
-111
lines changed

5 files changed

+179
-111
lines changed

examples/apps/infinite-scrolling/app.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable react/sort-comp */
22
import React, {Component} from "react";
33
import Radium from "radium";
4-
import debounce from "debounce";
4+
import debounce from "throttle-debounce/debounce";
55
import {Bling as Gpt, Events} from "react-gpt"; // eslint-disable-line import/no-unresolved
66
import "../log";
77
import Content from "./content";
@@ -40,14 +40,14 @@ class App extends Component {
4040
window.removeEventListener("resize", this.onScroll);
4141
this.stopTimer();
4242
}
43-
onScroll = debounce(() => {
43+
onScroll = debounce(66, () => {
4444
const scrollTop = window.scrollY || document.documentElement.scrollTop;
4545
if (scrollTop + window.innerHeight >= document.body.clientHeight) {
4646
this.setState({
4747
page: ++this.state.page
4848
});
4949
}
50-
}, 66)
50+
})
5151
startTimer() {
5252
this.stopTimer();
5353
this.timer = setInterval(() => {

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,11 @@
3232
"lib"
3333
],
3434
"dependencies": {
35-
"bundlesize": "^0.14.4",
36-
"debounce": "^1.0.0",
3735
"deep-equal": "^1.0.1",
3836
"eventemitter3": "^2.0.2",
3937
"fbjs": "^0.8.1",
40-
"hoist-non-react-statics": "^1.0.5"
38+
"hoist-non-react-statics": "^1.0.5",
39+
"throttle-debounce": "^1.0.1"
4140
},
4241
"devDependencies": {
4342
"babel-cli": "^6.5.1",
@@ -50,6 +49,7 @@
5049
"babel-preset-react": "^6.5.0",
5150
"babel-preset-stage-0": "^6.5.0",
5251
"babel-register": "^6.7.2",
52+
"bundlesize": "^0.14.4",
5353
"chai": "^3.4.1",
5454
"codecov.io": "^0.1.6",
5555
"commitizen": "^2.8.1",

src/createManager.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import EventEmitter from "eventemitter3";
2-
import debounce from "debounce";
2+
import {debounce, throttle} from "throttle-debounce";
33
import invariant from "fbjs/lib/invariant";
44
import {canUseDOM} from "fbjs/lib/ExecutionEnvironment";
55
import Events from "./Events";
@@ -131,14 +131,22 @@ export class AdManager extends EventEmitter {
131131
});
132132
}
133133

134-
_foldCheck = debounce(event => {
134+
_foldCheck = throttle(20, event => {
135135
const instances = this.getMountedInstances();
136136
instances.forEach(instance => {
137137
if (instance.getRenderWhenViewable()) {
138138
instance.foldCheck(event);
139139
}
140140
});
141-
}, 66)
141+
142+
if (this.testMode) {
143+
this._getTimer();
144+
}
145+
})
146+
147+
_getTimer() {
148+
return Date.now();
149+
}
142150

143151
_handleMediaQueryChange = event => {
144152
if (this._syncCorrelator) {
@@ -307,7 +315,7 @@ export class AdManager extends EventEmitter {
307315
return true;
308316
}
309317

310-
render = debounce(() => {
318+
render = debounce(4, () => {
311319
if (!this._initialRender) {
312320
return;
313321
}
@@ -375,7 +383,7 @@ export class AdManager extends EventEmitter {
375383

376384
this._initialRender = false;
377385
});
378-
}, 4)
386+
})
379387

380388
/**
381389
* Re-render(not refresh) all the ads in the page and the first ad will update the correlator value.
@@ -384,7 +392,7 @@ export class AdManager extends EventEmitter {
384392
* @method renderAll
385393
* @static
386394
*/
387-
renderAll = debounce(() => {
395+
renderAll = debounce(4, () => {
388396
if (!this.apiReady) {
389397
return false;
390398
}
@@ -399,7 +407,7 @@ export class AdManager extends EventEmitter {
399407
});
400408

401409
return true;
402-
}, 4)
410+
})
403411

404412
getGPTVersion() {
405413
if (!this.apiReady) {

test/createManager.spec.js

+29-7
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ describe("createManager", () => {
399399
adManager.render();
400400
});
401401

402-
it("debounces foldCheck", (done) => {
402+
it("throttles foldCheck", (done) => {
403403
const instance = {
404404
props: {
405405
sizeMapping: [{viewport: [0, 0], slot: [320, 50]}]
@@ -422,23 +422,45 @@ describe("createManager", () => {
422422

423423
const foldCheck = sinon.stub(instance, "foldCheck");
424424
const foldCheck2 = sinon.stub(instance2, "foldCheck");
425+
const getRenderWhenViewable = sinon.spy(instance, "getRenderWhenViewable");
426+
const getRenderWhenViewable2 = sinon.spy(instance2, "getRenderWhenViewable");
427+
const managerFoldCheck = sinon.spy(adManager, "_foldCheck");
428+
const timer = sinon.spy(adManager, "_getTimer");
425429

426430
adManager.addInstance(instance);
427431
adManager.addInstance(instance2);
428432

433+
const start = Date.now();
434+
adManager._foldCheck();
435+
adManager._foldCheck();
436+
setTimeout(() => {
437+
adManager._foldCheck();
438+
}, 5);
439+
setTimeout(() => {
440+
adManager._foldCheck();
441+
}, 10);
442+
setTimeout(() => {
443+
adManager._foldCheck();
444+
}, 15);
445+
429446
setTimeout(() => {
430-
expect(foldCheck.calledOnce).to.be.true;
431-
expect(foldCheck2.calledOnce).to.be.false;
447+
expect(managerFoldCheck.callCount).to.equal(5);
448+
expect(timer.calledTwice).to.be.true;
449+
expect(timer.returnValues[1] - timer.returnValues[0]).to.be.above(19); // timer above 20ms timeout
450+
expect(timer.returnValues[0] - start).to.be.below(5); // should start ~immediately
451+
expect(foldCheck.calledTwice).to.be.true;
452+
expect(foldCheck2.notCalled).to.be.true;
453+
432454
foldCheck.restore();
433455
foldCheck2.restore();
456+
getRenderWhenViewable.restore();
457+
getRenderWhenViewable2.restore();
458+
managerFoldCheck.restore();
459+
timer.restore();
434460
adManager.removeInstance(instance);
435461
adManager.removeInstance(instance2);
436462
done();
437463
}, 100);
438-
439-
adManager._foldCheck();
440-
adManager._foldCheck();
441-
adManager._foldCheck();
442464
});
443465

444466
it("renders all ads", (done) => {

0 commit comments

Comments
 (0)