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

Commit

Permalink
perf(view factory): 14% Precompute linking information for nodes
Browse files Browse the repository at this point in the history
The Default TreeComponent benchmark dropped from 572ms to 501ms

Closes #1194
Closes #1196
  • Loading branch information
jbdeboer committed Jul 1, 2014
1 parent 6161600 commit eac36d1
Showing 1 changed file with 56 additions and 13 deletions.
69 changes: 56 additions & 13 deletions lib/core_dom/tagging_view_factory.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,55 @@
part of angular.core.dom_internal;

class NodeLinkingInfo {
/**
* True if the Node has a 'ng-binding' class.
*/
final bool containsNgBinding;

/**
* True if the Node is a [dom.Element], otherwise it is a Text or Comment node.
* No other nodeTypes are allowed.
*/
final bool isElement;

/**
* If true, some child has a 'ng-binding' class and the ViewFactory must search
* for these children.
*/
final bool ngBindingChildren;

NodeLinkingInfo(this.containsNgBinding, this.isElement, this.ngBindingChildren);
}

computeNodeLinkingInfos(List<dom.Node> nodeList) {
List<NodeLinkingInfo> list = new List<NodeLinkingInfo>(nodeList.length);

for (int i = 0; i < nodeList.length; i++) {
dom.Node node = nodeList[i];

assert(node.nodeType == dom.Node.ELEMENT_NODE ||
node.nodeType == dom.Node.TEXT_NODE ||
node.nodeType == dom.Node.COMMENT_NODE);

bool isElement = node.nodeType == dom.Node.ELEMENT_NODE;

list[i] = new NodeLinkingInfo(
isElement && (node as dom.Element).classes.contains('ng-binding'),
isElement,
isElement && (node as dom.Element).querySelectorAll('.ng-binding').length > 0);
}
return list;
}

class TaggingViewFactory implements ViewFactory {
final List<TaggedElementBinder> elementBinders;
final List<dom.Node> templateNodes;
final List<NodeLinkingInfo> nodeLinkingInfos;
final Profiler _perf;

TaggingViewFactory(this.templateNodes, this.elementBinders, this._perf);
TaggingViewFactory(templateNodes, this.elementBinders, this._perf) :
nodeLinkingInfos = computeNodeLinkingInfos(templateNodes),
this.templateNodes = templateNodes;

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

Expand Down Expand Up @@ -51,7 +95,8 @@ class TaggingViewFactory implements ViewFactory {

var elementBinderIndex = 0;
for (int i = 0; i < nodeList.length; i++) {
var node = nodeList[i];
dom.Node node = nodeList[i];
NodeLinkingInfo linkingInfo = nodeLinkingInfos[i];

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

if (node.nodeType == dom.Node.ELEMENT_NODE) {
var elts = node.querySelectorAll('.ng-binding');
// querySelectorAll doesn't return the node itself
if (node.classes.contains('ng-binding')) {
if (linkingInfo.isElement) {
if (linkingInfo.containsNgBinding) {
var tagged = elementBinders[elementBinderIndex];
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
elementBinderIndex++;
}

for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
if (linkingInfo.ngBindingChildren) {
var elts = (node as dom.Element).querySelectorAll('.ng-binding');
for (int j = 0; j < elts.length; j++, elementBinderIndex++) {
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, elts[j]);
}
}
} else if (node.nodeType == dom.Node.TEXT_NODE ||
node.nodeType == dom.Node.COMMENT_NODE) {
} else {
TaggedElementBinder tagged = elementBinders[elementBinderIndex];
assert(tagged.binder != null || tagged.isTopLevel);
if (tagged.binder != null) {
_bindTagged(tagged, elementBinderIndex, rootInjector, elementInjectors, view, node);
}
elementBinderIndex++;
} else {
throw "nodeType sadness ${node.nodeType}}";
}

if (fakeParent) {
Expand Down

0 comments on commit eac36d1

Please sign in to comment.