Skip to content

Commit 2df536b

Browse files
committed
Implementing a cache for the gettersProxy object creation. Kill ssr performance wth large number of modules/getters
1 parent d7c7f98 commit 2df536b

File tree

3 files changed

+16864
-40
lines changed

3 files changed

+16864
-40
lines changed

Diff for: dist/vuex.common.js

+43-22
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ function applyMixin (Vue) {
4141
}
4242
}
4343

44-
var devtoolHook =
45-
typeof window !== 'undefined' &&
46-
window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
44+
var target = typeof window !== 'undefined'
45+
? window
46+
: typeof global !== 'undefined'
47+
? global
48+
: {};
49+
var devtoolHook = target.__VUE_DEVTOOLS_GLOBAL_HOOK__;
4750

4851
function devtoolPlugin (store) {
4952
if (!devtoolHook) { return }
@@ -89,6 +92,12 @@ function assert (condition, msg) {
8992
if (!condition) { throw new Error(("[vuex] " + msg)) }
9093
}
9194

95+
function partial (fn, arg) {
96+
return function () {
97+
return fn(arg)
98+
}
99+
}
100+
92101
// Base data struct for store's module, package with some attribute and method
93102
var Module = function Module (rawModule, runtime) {
94103
this.runtime = runtime;
@@ -550,7 +559,9 @@ function resetStoreVM (store, state, hot) {
550559
var computed = {};
551560
forEachValue(wrappedGetters, function (fn, key) {
552561
// use computed to leverage its lazy-caching mechanism
553-
computed[key] = function () { return fn(store); };
562+
// direct inline function use will lead to closure preserving oldVm.
563+
// using partial to return function with only arguments preserved in closure enviroment.
564+
computed[key] = partial(fn, store);
554565
Object.defineProperty(store.getters, key, {
555566
get: function () { return store._vm[key]; },
556567
enumerable: true // for local getters
@@ -687,27 +698,37 @@ function makeLocalContext (store, namespace, path) {
687698
return local
688699
}
689700

701+
var makeLocalGettersCache = {};
702+
var cacheStore = {};
703+
690704
function makeLocalGetters (store, namespace) {
691-
var gettersProxy = {};
692-
693-
var splitPos = namespace.length;
694-
Object.keys(store.getters).forEach(function (type) {
695-
// skip if the target getter is not match this namespace
696-
if (type.slice(0, splitPos) !== namespace) { return }
697-
698-
// extract local getter type
699-
var localType = type.slice(splitPos);
700-
701-
// Add a port to the getters proxy.
702-
// Define as getter property because
703-
// we do not want to evaluate the getters in this time.
704-
Object.defineProperty(gettersProxy, localType, {
705-
get: function () { return store.getters[type]; },
706-
enumerable: true
705+
if (cacheStore !== store) {
706+
makeLocalGettersCache = {};
707+
cacheStore = store;
708+
}
709+
710+
if (!makeLocalGettersCache[namespace]) {
711+
var gettersProxy = {};
712+
var splitPos = namespace.length;
713+
Object.keys(store.getters).forEach(function (type) {
714+
// skip if the target getter is not match this namespace
715+
if (type.slice(0, splitPos) !== namespace) { return }
716+
717+
// extract local getter type
718+
var localType = type.slice(splitPos);
719+
720+
// Add a port to the getters proxy.
721+
// Define as getter property because
722+
// we do not want to evaluate the getters in this time.
723+
Object.defineProperty(gettersProxy, localType, {
724+
get: function () { return store.getters[type]; },
725+
enumerable: true
726+
});
707727
});
708-
});
728+
makeLocalGettersCache[namespace] = gettersProxy;
729+
}
709730

710-
return gettersProxy
731+
return makeLocalGettersCache[namespace]
711732
}
712733

713734
function registerMutation (store, type, handler, local) {

0 commit comments

Comments
 (0)