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

Commit eac36d1

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 6161600 commit eac36d1

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
@@ -1,11 +1,55 @@
11
part of angular.core.dom_internal;
22

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

8-
TaggingViewFactory(this.templateNodes, this.elementBinders, this._perf);
50+
TaggingViewFactory(templateNodes, this.elementBinders, this._perf) :
51+
nodeLinkingInfos = computeNodeLinkingInfos(templateNodes),
52+
this.templateNodes = templateNodes;
953

1054
BoundViewFactory bind(Injector injector) => new BoundViewFactory(this, injector);
1155

@@ -51,7 +95,8 @@ class TaggingViewFactory implements ViewFactory {
5195

5296
var elementBinderIndex = 0;
5397
for (int i = 0; i < nodeList.length; i++) {
54-
var node = nodeList[i];
98+
dom.Node node = nodeList[i];
99+
NodeLinkingInfo linkingInfo = nodeLinkingInfos[i];
55100

56101
// if node isn't attached to the DOM, create a parent for it.
57102
var parentNode = node.parentNode;
@@ -62,29 +107,27 @@ class TaggingViewFactory implements ViewFactory {
62107
parentNode.append(node);
63108
}
64109

65-
if (node.nodeType == dom.Node.ELEMENT_NODE) {
66-
var elts = node.querySelectorAll('.ng-binding');
67-
// querySelectorAll doesn't return the node itself
68-
if (node.classes.contains('ng-binding')) {
110+
if (linkingInfo.isElement) {
111+
if (linkingInfo.containsNgBinding) {
69112
var tagged = elementBinders[elementBinderIndex];
70113
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
71114
elementBinderIndex++;
72115
}
73116

74-
for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
75-
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
76-
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
117+
if (linkingInfo.ngBindingChildren) {
118+
var elts = (node as dom.Element).querySelectorAll('.ng-binding');
119+
for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
120+
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
121+
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
122+
}
77123
}
78-
} else if (node.nodeType == dom.Node.TEXT_NODE ||
79-
node.nodeType == dom.Node.COMMENT_NODE) {
124+
} else {
80125
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
81126
assert(tagged.binder != null || tagged.isTopLevel);
82127
if (tagged.binder != null) {
83128
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
84129
}
85130
elementBinderIndex++;
86-
} else {
87-
throw "nodeType sadness ${node.nodeType}}";
88131
}
89132

90133
if (fakeParent) {

0 commit comments

Comments
 (0)