Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit afff985

Browse files
committed
perf(view factory): 14% Precompute linking information for nodes
The Default TreeComponent benchmark dropped from 572ms to 501ms Closes #1194 Closes #1196
1 parent f2b8393 commit afff985

File tree

1 file changed

+56
-13
lines changed

1 file changed

+56
-13
lines changed

lib/core_dom/tagging_view_factory.dart

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,56 @@ part of angular.core.dom_internal;
22

33
var ngViewTag = new UserTag('NgView');
44

5+
class NodeLinkingInfo {
6+
/**
7+
* True if the Node has a 'ng-binding' class.
8+
*/
9+
final bool containsNgBinding;
10+
11+
/**
12+
* True if the Node is a [dom.Element], otherwise it is a Text or Comment node.
13+
* No other nodeTypes are allowed.
14+
*/
15+
final bool isElement;
16+
17+
/**
18+
* If true, some child has a 'ng-binding' class and the ViewFactory must search
19+
* for these children.
20+
*/
21+
final bool ngBindingChildren;
22+
23+
NodeLinkingInfo(this.containsNgBinding, this.isElement, this.ngBindingChildren);
24+
}
25+
26+
computeNodeLinkingInfos(List<dom.Node> nodeList) {
27+
List<NodeLinkingInfo> list = new List<NodeLinkingInfo>(nodeList.length);
28+
29+
for (int i = 0; i < nodeList.length; i++) {
30+
dom.Node node = nodeList[i];
31+
32+
assert(node.nodeType == dom.Node.ELEMENT_NODE ||
33+
node.nodeType == dom.Node.TEXT_NODE ||
34+
node.nodeType == dom.Node.COMMENT_NODE);
35+
36+
bool isElement = node.nodeType == dom.Node.ELEMENT_NODE;
37+
38+
list[i] = new NodeLinkingInfo(
39+
isElement && (node as dom.Element).classes.contains('ng-binding'),
40+
isElement,
41+
isElement && (node as dom.Element).querySelectorAll('.ng-binding').length > 0);
42+
}
43+
return list;
44+
}
45+
546
class TaggingViewFactory implements ViewFactory {
647
final List<TaggedElementBinder> elementBinders;
748
final List<dom.Node> templateNodes;
49+
final List<NodeLinkingInfo> nodeLinkingInfos;
850
final Profiler _perf;
951

10-
TaggingViewFactory(this.templateNodes, this.elementBinders, this._perf);
52+
TaggingViewFactory(templateNodes, this.elementBinders, this._perf) :
53+
nodeLinkingInfos = computeNodeLinkingInfos(templateNodes),
54+
this.templateNodes = templateNodes;
1155

1256
BoundViewFactory bind(Injector injector) => new BoundViewFactory(this, injector);
1357

@@ -55,7 +99,8 @@ class TaggingViewFactory implements ViewFactory {
5599

56100
var elementBinderIndex = 0;
57101
for (int i = 0; i < nodeList.length; i++) {
58-
var node = nodeList[i];
102+
dom.Node node = nodeList[i];
103+
NodeLinkingInfo linkingInfo = nodeLinkingInfos[i];
59104

60105
// if node isn't attached to the DOM, create a parent for it.
61106
var parentNode = node.parentNode;
@@ -66,29 +111,27 @@ class TaggingViewFactory implements ViewFactory {
66111
parentNode.append(node);
67112
}
68113

69-
if (node.nodeType == dom.Node.ELEMENT_NODE) {
70-
var elts = node.querySelectorAll('.ng-binding');
71-
// querySelectorAll doesn't return the node itself
72-
if (node.classes.contains('ng-binding')) {
114+
if (linkingInfo.isElement) {
115+
if (linkingInfo.containsNgBinding) {
73116
var tagged = elementBinders[elementBinderIndex];
74117
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
75118
elementBinderIndex++;
76119
}
77120

78-
for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
79-
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
80-
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
121+
if (linkingInfo.ngBindingChildren) {
122+
var elts = (node as dom.Element).querySelectorAll('.ng-binding');
123+
for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
124+
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
125+
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
126+
}
81127
}
82-
} else if (node.nodeType == dom.Node.TEXT_NODE ||
83-
node.nodeType == dom.Node.COMMENT_NODE) {
128+
} else {
84129
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
85130
assert(tagged.binder != null || tagged.isTopLevel);
86131
if (tagged.binder != null) {
87132
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
88133
}
89134
elementBinderIndex++;
90-
} else {
91-
throw "nodeType sadness ${node.nodeType}}";
92135
}
93136

94137
if (fakeParent) {

0 commit comments

Comments
 (0)