From ef0efa6ee6b990019741114486e949824ec88e89 Mon Sep 17 00:00:00 2001 From: Kevin Schaaf Date: Tue, 5 Mar 2019 11:15:31 -0800 Subject: [PATCH] Add hasPaths optimziation --- lib/mixins/property-effects.js | 39 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/mixins/property-effects.js b/lib/mixins/property-effects.js index c6164ffc38..11b6ced9dc 100644 --- a/lib/mixins/property-effects.js +++ b/lib/mixins/property-effects.js @@ -439,20 +439,21 @@ const TRANSITIVE_DEPENDENCY = '~transitive~dependency~'; * @param {?Object} changedProps Bag of current property changes * @param {?Object} oldProps Bag of previous values for changed properties * @param {?} info Effect metadata + * @param {boolean} hasPaths True with `changedProps` contains one or more paths * @return {void} * @private */ -function runComputedEffect(inst, property, changedProps, oldProps, info) { +function runComputedEffect(inst, property, changedProps, oldProps, info, hasPaths) { if (orderedComputed) { // Compute any computed dependencies first; this recurses through the // dependency graph to ensure computed properties are never computed with // dependencies that may become invalidated later in this turn - computeDependencies(inst, info, changedProps, oldProps); + computeDependencies(inst, info, changedProps, oldProps, hasPaths); // If the dependency was not transitive, it's definitely dirty and needs to // be computed; if it is transitive, check its arguments against the current // changed props and only re-compute if it is dirty if (property === TRANSITIVE_DEPENDENCY && - !computedPropertyIsDirty(inst, info, changedProps)) { + !computedPropertyIsDirty(inst, info, changedProps, hasPaths)) { return; } } @@ -502,16 +503,17 @@ function runComputedEffect(inst, property, changedProps, oldProps, info) { * @param {Object} info Effect metadata * @param {Object} changedProps Bag of current property changes * @param {Object} oldProps Bag of previous values for changed properties + * @param {boolean} hasPaths True with `changedProps` contains one or more paths * @return {void} * @private */ - function computeDependencies(inst, info, changedProps, oldProps) { + function computeDependencies(inst, info, changedProps, oldProps, hasPaths) { let deps = computedDependenciesFor(inst, info); if (deps.length) { deps.forEach(depInfo => { if (depInfo.lastRun !== info.lastRun) { depInfo.lastRun = info.lastRun; - runComputedEffect(inst, TRANSITIVE_DEPENDENCY, changedProps, oldProps, depInfo); + runComputedEffect(inst, TRANSITIVE_DEPENDENCY, changedProps, oldProps, depInfo, hasPaths); } }); } @@ -523,12 +525,13 @@ function runComputedEffect(inst, property, changedProps, oldProps, info) { * @param {!Polymer_PropertyEffects} inst The instance to test * @param {?} info Effect metadata * @param {Object} changedProps Bag of current property changes + * @param {boolean} hasPaths True with `changedProps` contains one or more paths * @return {boolean} true when the computed effect should be re-calculated * @private */ -function computedPropertyIsDirty(inst, info, changedProps) { - return info.dynamicFn && propertyIsDirty(inst, {name: info.methodName}, changedProps) || - info.args.some(arg => propertyIsDirty(inst, arg, changedProps)); +function computedPropertyIsDirty(inst, info, changedProps, hasPaths) { + return info.dynamicFn && propertyIsDirty(inst, {rootProperty: info.methodName}, changedProps, hasPaths) || + info.args.some(arg => propertyIsDirty(inst, arg, changedProps, hasPaths)); } /** @@ -537,17 +540,23 @@ function computedPropertyIsDirty(inst, info, changedProps) { * @param {!Polymer_PropertyEffects} inst The instance to test * @param {DataTrigger} trigger Descriptor * @param {Object} changedProps Bag of current property changes + * @param {boolean} hasPaths True with `changedProps` contains one or more paths * @return {boolean} true when the property is dirty * @private */ -function propertyIsDirty(inst, trigger, changedProps) { - return [changedProps, inst.__dataPending].some(props => { - for (let p in props) { - if (pathMatchesTrigger(p, trigger)) { - return true; +function propertyIsDirty(inst, trigger, changedProps, hasPaths) { + if (hasPaths) { + [changedProps, inst.__dataPending].some(props => { + for (let p in props) { + if (pathMatchesTrigger(p, trigger)) { + return true; + } } - } - }); + }); + } else { + return changedProps && trigger.rootProperty in changedProps || + inst.__dataPending && trigger.rootProperty in inst.__dataPending; + } } /**