Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit b5f7970

Browse files
committed
perf($compile): don't register $destroy callbacks on element-transcluded nodes
This is a major perf win in the large table benchmark (~100ms or 9). This cleanup is needed only for regular transclusion because only then the DOM hierarchy doesn't match scope hierarchy (transcluded scope is a child of the parent scope and not a child of the isolate scope) We should consider refactoring this further for the case of regular transclusion and consider using scope events instead.
1 parent d05f27e commit b5f7970

File tree

2 files changed

+9
-6
lines changed

2 files changed

+9
-6
lines changed

src/ng/compile.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10001000
}
10011001

10021002
if ( nodeLinkFn.transcludeOnThisElement ) {
1003-
childBoundTranscludeFn = createBoundTranscludeFn(scope, nodeLinkFn.transclude, parentBoundTranscludeFn);
1003+
childBoundTranscludeFn = createBoundTranscludeFn(
1004+
scope, nodeLinkFn.transclude, parentBoundTranscludeFn,
1005+
nodeLinkFn.elementTranscludeOnThisElement);
10041006

10051007
} else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {
10061008
childBoundTranscludeFn = parentBoundTranscludeFn;
@@ -1021,7 +1023,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10211023
}
10221024
}
10231025

1024-
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {
1026+
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn, elementTransclusion) {
10251027

10261028
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers) {
10271029
var scopeCreated = false;
@@ -1033,7 +1035,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10331035
}
10341036

10351037
var clone = transcludeFn(transcludedScope, cloneFn, controllers, previousBoundTranscludeFn);
1036-
if (scopeCreated) {
1038+
if (scopeCreated && !elementTransclusion) {
10371039
clone.on('$destroy', function() { transcludedScope.$destroy(); });
10381040
}
10391041
return clone;
@@ -1410,6 +1412,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
14101412

14111413
nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;
14121414
nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;
1415+
nodeLinkFn.elementTranscludeOnThisElement = hasElementTranscludeDirective;
14131416
nodeLinkFn.templateOnThisElement = hasTemplate;
14141417
nodeLinkFn.transclude = childTranscludeFn;
14151418

test/ng/compileSpec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -4128,16 +4128,16 @@ describe('$compile', function() {
41284128
function testCleanup() {
41294129
var privateData, firstRepeatedElem;
41304130

4131-
element = $compile('<div><div ng-repeat="x in xs">{{x}}</div></div>')($rootScope);
4131+
element = $compile('<div><div ng-repeat="x in xs" ng-click="noop()">{{x}}</div></div>')($rootScope);
41324132

41334133
$rootScope.$apply('xs = [' + xs + ']');
41344134
firstRepeatedElem = element.children('.ng-scope').eq(0);
41354135

41364136
expect(firstRepeatedElem.data('$scope')).toBeDefined();
41374137
privateData = jQuery._data(firstRepeatedElem[0]);
41384138
expect(privateData.events).toBeDefined();
4139-
expect(privateData.events.$destroy).toBeDefined();
4140-
expect(privateData.events.$destroy[0]).toBeDefined();
4139+
expect(privateData.events.click).toBeDefined();
4140+
expect(privateData.events.click[0]).toBeDefined();
41414141

41424142
$rootScope.$apply('xs = null');
41434143

0 commit comments

Comments
 (0)