From 9ae0c01c2bcaff2f3906eec574f9c6ed8abde14a Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Sun, 26 Oct 2014 16:00:08 -0700 Subject: [PATCH] perf($compile): only re-$interpolate attribute values at link time if changed since compile --- benchmarks/largetable-bp/main.html | 7 +++++++ src/ng/compile.js | 21 ++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/benchmarks/largetable-bp/main.html b/benchmarks/largetable-bp/main.html index 084068da..f40353cb 100644 --- a/benchmarks/largetable-bp/main.html +++ b/benchmarks/largetable-bp/main.html @@ -14,6 +14,7 @@
ngBind:
ngBindOnce:
interpolation:
+
attribute interpolation:
ngBind + fnInvocation:
interpolation + fnInvocation:
ngBind + filter:
@@ -46,6 +47,12 @@ {{column.i}}:{{column.j}}| +
+

attribute interpolation

+
+ i,j attrs +
+

bindings with functions

diff --git a/src/ng/compile.js b/src/ng/compile.js index 41083149..387d6a40 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -2335,7 +2335,10 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) { - var interpolateFn = $interpolate(value, true); + var trustedContext = getTrustedContext(node, name); + allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing; + + var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing); // no interpolation found -> ignore if (!interpolateFn) return; @@ -2360,16 +2363,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { "ng- versions (such as ng-click instead of onclick) instead."); } - // If the attribute was removed, then we are done - if (!attr[name]) { - return; + // If the attribute has changed since last $interpolate()ed + var newValue = attr[name]; + if (newValue !== value) { + // we need to interpolate again since the attribute value has been updated + // (e.g. by another directive's compile function) + // ensure unset/empty values make interpolateFn falsy + interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing); + value = newValue; } - // we need to interpolate again, in case the attribute value has been updated - // (e.g. by another directive's compile function) - interpolateFn = $interpolate(attr[name], true, getTrustedContext(node, name), - ALL_OR_NOTHING_ATTRS[name] || allOrNothing); - // if attribute was updated so that there is no interpolation going on we don't want to // register any observers if (!interpolateFn) return;