perf(render): precompute # bound text nodes and root nodes in `DomProtoView`
This commit is contained in:
parent
9cd510abaa
commit
24e647e0f7
|
@ -102,7 +102,7 @@ class Html5LibDomAdapter implements DomAdapter {
|
||||||
throw 'not implemented';
|
throw 'not implemented';
|
||||||
}
|
}
|
||||||
content(node) {
|
content(node) {
|
||||||
throw 'not implemented';
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
firstChild(el) => el is NodeList ? el.first : el.firstChild;
|
firstChild(el) => el is NodeList ? el.first : el.firstChild;
|
||||||
|
|
|
@ -224,13 +224,11 @@ export class DomRenderer extends Renderer {
|
||||||
rootElementClone = DOM.importIntoDoc(DOM.content(protoView.element));
|
rootElementClone = DOM.importIntoDoc(DOM.content(protoView.element));
|
||||||
elementsWithBindingsDynamic =
|
elementsWithBindingsDynamic =
|
||||||
DOM.querySelectorAll(rootElementClone, NG_BINDING_CLASS_SELECTOR);
|
DOM.querySelectorAll(rootElementClone, NG_BINDING_CLASS_SELECTOR);
|
||||||
var childNode = DOM.firstChild(rootElementClone);
|
viewRootNodes = ListWrapper.createFixedSize(protoView.rootNodeCount);
|
||||||
// TODO(perf): Should be fixed size, since we could pre-compute in in DomProtoView
|
|
||||||
viewRootNodes = [];
|
|
||||||
// Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
|
// Note: An explicit loop is the fastest way to convert a DOM array into a JS array!
|
||||||
while (childNode != null) {
|
var childNode = DOM.firstChild(rootElementClone);
|
||||||
ListWrapper.push(viewRootNodes, childNode);
|
for (var i = 0; i < protoView.rootNodeCount; i++, childNode = DOM.nextSibling(childNode)) {
|
||||||
childNode = DOM.nextSibling(childNode);
|
viewRootNodes[i] = childNode;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rootElementClone = DOM.importIntoDoc(protoView.element);
|
rootElementClone = DOM.importIntoDoc(protoView.element);
|
||||||
|
@ -239,8 +237,9 @@ export class DomRenderer extends Renderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
var binders = protoView.elementBinders;
|
var binders = protoView.elementBinders;
|
||||||
var boundTextNodes = [];
|
var boundTextNodes = ListWrapper.createFixedSize(protoView.boundTextNodeCount);
|
||||||
var boundElements = ListWrapper.createFixedSize(binders.length);
|
var boundElements = ListWrapper.createFixedSize(binders.length);
|
||||||
|
var boundTextNodeIdx = 0;
|
||||||
|
|
||||||
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
for (var binderIdx = 0; binderIdx < binders.length; binderIdx++) {
|
||||||
var binder = binders[binderIdx];
|
var binder = binders[binderIdx];
|
||||||
|
@ -261,7 +260,7 @@ export class DomRenderer extends Renderer {
|
||||||
// boundTextNodes
|
// boundTextNodes
|
||||||
var textNodeIndices = binder.textNodeIndices;
|
var textNodeIndices = binder.textNodeIndices;
|
||||||
for (var i = 0; i < textNodeIndices.length; i++) {
|
for (var i = 0; i < textNodeIndices.length; i++) {
|
||||||
ListWrapper.push(boundTextNodes, childNodes[textNodeIndices[i]]);
|
boundTextNodes[boundTextNodeIdx++] = childNodes[textNodeIndices[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// contentTags
|
// contentTags
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent} from 'angular2/src/facade/lang';
|
||||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||||
|
|
||||||
import {List} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {ElementBinder} from './element_binder';
|
import {ElementBinder} from './element_binder';
|
||||||
import {NG_BINDING_CLASS} from '../util';
|
import {NG_BINDING_CLASS} from '../util';
|
||||||
|
@ -27,6 +27,8 @@ export class DomProtoView {
|
||||||
rootBindingOffset: number;
|
rootBindingOffset: number;
|
||||||
// the number of content tags seen in this or any child proto view.
|
// the number of content tags seen in this or any child proto view.
|
||||||
transitiveContentTagCount: number;
|
transitiveContentTagCount: number;
|
||||||
|
boundTextNodeCount: number;
|
||||||
|
rootNodeCount: number;
|
||||||
|
|
||||||
constructor({elementBinders, element, transitiveContentTagCount}) {
|
constructor({elementBinders, element, transitiveContentTagCount}) {
|
||||||
this.element = element;
|
this.element = element;
|
||||||
|
@ -35,5 +37,11 @@ export class DomProtoView {
|
||||||
this.isTemplateElement = DOM.isTemplateElement(this.element);
|
this.isTemplateElement = DOM.isTemplateElement(this.element);
|
||||||
this.rootBindingOffset =
|
this.rootBindingOffset =
|
||||||
(isPresent(this.element) && DOM.hasClass(this.element, NG_BINDING_CLASS)) ? 1 : 0;
|
(isPresent(this.element) && DOM.hasClass(this.element, NG_BINDING_CLASS)) ? 1 : 0;
|
||||||
|
this.boundTextNodeCount =
|
||||||
|
ListWrapper.reduce(elementBinders, (prevCount: number, elementBinder: ElementBinder) =>
|
||||||
|
prevCount + elementBinder.textNodeIndices.length,
|
||||||
|
0);
|
||||||
|
this.rootNodeCount =
|
||||||
|
this.isTemplateElement ? DOM.childNodes(DOM.content(this.element)).length : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue