-
Notifications
You must be signed in to change notification settings - Fork 27.4k
perf($compile): only iterate over elements with link functions #8741
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -960,7 +960,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { | |
function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, | ||
previousCompileContext) { | ||
var linkFns = [], | ||
attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound; | ||
attrs, directives, nodeLinkFn, childNodes, childLinkFn, nodeLinkFnFound; | ||
|
||
for (var i = 0; i < nodeList.length; i++) { | ||
attrs = new Attributes(); | ||
|
@@ -987,38 +987,39 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { | |
(nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) | ||
&& nodeLinkFn.transclude) : transcludeFn); | ||
|
||
linkFns.push(nodeLinkFn, childLinkFn); | ||
linkFnFound = linkFnFound || nodeLinkFn || childLinkFn; | ||
nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn; | ||
if (nodeLinkFn || childLinkFn) { | ||
linkFns.push(i, nodeLinkFn, childLinkFn); | ||
nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn; | ||
} | ||
|
||
//use the previous context only for the first element in the virtual group | ||
previousCompileContext = null; | ||
} | ||
|
||
// return a linking function if we have found anything, null otherwise | ||
return linkFnFound ? compositeLinkFn : null; | ||
return linkFns.length ? compositeLinkFn : null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. revert |
||
|
||
function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { | ||
var nodeLinkFn, childLinkFn, node, childScope, i, ii, n, childBoundTranscludeFn; | ||
var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn; | ||
var stableNodeList; | ||
|
||
|
||
if (nodeLinkFnFound) { | ||
// copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our | ||
// offsets don't get screwed up | ||
var nodeListLength = nodeList.length; | ||
stableNodeList = new Array(nodeListLength); | ||
stableNodeList = []; | ||
|
||
for (i = 0; i < nodeListLength; i++) { | ||
stableNodeList[i] = nodeList[i]; | ||
// create a sparse array by only copying the elements which have a linkFn | ||
for (i = 0, ii = linkFns.length; i < ii; i+=3) { | ||
idx = linkFns[i]; | ||
stableNodeList[idx] = nodeList[idx]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you are creating sparse arrays here. that will disable all major array optimizations in the VM. we need to avoid that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could just revert this block then. Or could the sparse array lookups be worth the shorter array and loop? Or make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about this more and getting rid of the sparse array is not that easy as it makes code in the later loop more complicated. we should at least prealocate the array as we used to. |
||
} | ||
} else { | ||
stableNodeList = nodeList; | ||
} | ||
|
||
// TODO(perf): when the DOM is sparsely annotated with directives, we spend a lot of time iterating over nulls here | ||
for(i = 0, n = 0, ii = linkFns.length; i < ii; n++) { | ||
node = stableNodeList[n]; | ||
for(i = 0, ii = linkFns.length; i < ii; ) { | ||
node = stableNodeList[ linkFns[i++] ]; | ||
nodeLinkFn = linkFns[i++]; | ||
childLinkFn = linkFns[i++]; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that getting rid of the linkFnFound var makes things better/faster/more readable. I'd keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely not faster. I personally thought it was more readable but I'll revert it if you prefer the flag.