-
Notifications
You must be signed in to change notification settings - Fork 7.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: Cache currentTime and buffered from Flash (#3705)
Calling into the SWF too often is expensive. Current time and buffered don't actually change that often but it's very common to call them a couple times in the handling of a single event. Cache their return values for 100ms so the performance penalty of going through ExternalInterface is limited.
- Loading branch information
Showing
4 changed files
with
137 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* @file flash-cache.js | ||
* | ||
* Auto-caching method wrapper to avoid calling through to Flash too | ||
* often. | ||
*/ | ||
|
||
/** | ||
* Returns a new getter function that returns a cached value if | ||
* invoked multiple times within the specified duration. | ||
* | ||
* @param {Function} getter the function to be cached | ||
* @param {Number} cacheDuration the number of milliseconds to cache | ||
* results for | ||
* @return {Function} a new function that returns cached results if | ||
* invoked multiple times within the cache duration | ||
*/ | ||
export default function timeExpiringCache(getter, cacheDuration) { | ||
const result = function cachedGetter() { | ||
const now = new Date().getTime(); | ||
|
||
if (now - result.lastCheckTime_ >= cacheDuration) { | ||
result.lastCheckTime_ = now; | ||
result.cache_ = getter(); | ||
} | ||
return result.cache_; | ||
}; | ||
|
||
result.lastCheckTime_ = -Infinity; | ||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* eslint-env qunit */ | ||
import timeExpiringCache from '../../../src/js/tech/flash-cache.js'; | ||
import sinon from 'sinon'; | ||
|
||
QUnit.module('Flash Cache', { | ||
beforeEach() { | ||
this.clock = sinon.useFakeTimers(); | ||
}, | ||
afterEach() { | ||
this.clock.restore(); | ||
} | ||
}); | ||
|
||
QUnit.test('calls the getter on first invocation', function(assert) { | ||
let calls = 0; | ||
const cached = timeExpiringCache(() => calls++, 100); | ||
|
||
QUnit.equal(cached(), 0, 'returned a value'); | ||
QUnit.equal(calls, 1, 'called the getter'); | ||
}); | ||
|
||
QUnit.test('caches results', function(assert) { | ||
let calls = 0; | ||
const cached = timeExpiringCache(() => calls++, 100); | ||
|
||
for (let i = 0; i < 31; i++) { | ||
QUnit.equal(cached(), 0, 'returned a cached value'); | ||
} | ||
QUnit.equal(calls, 1, 'only called getter once'); | ||
}); | ||
|
||
QUnit.test('refreshes the cache after the result expires', function(assert) { | ||
let calls = 0; | ||
const cached = timeExpiringCache(() => calls++, 1); | ||
|
||
QUnit.equal(cached(), 0, 'returned a value'); | ||
QUnit.equal(cached(), 0, 'returned a cached value'); | ||
QUnit.equal(calls, 1, 'only called getter once'); | ||
this.clock.tick(1); | ||
|
||
QUnit.equal(cached(), 1, 'returned a value'); | ||
QUnit.equal(cached(), 1, 'returned a cached value'); | ||
QUnit.equal(calls, 2, 'called getter again'); | ||
|
||
this.clock.tick(10); | ||
QUnit.equal(calls, 2, 'only refreshes on-demand'); | ||
QUnit.equal(cached(), 2, 'returned a value'); | ||
QUnit.equal(cached(), 2, 'returned a cached value'); | ||
QUnit.equal(calls, 3, 'called getter again'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters