fix(render): only look for content tags in views that might have them.
Largetable benchmark with `interpolationAttr` and 200 rows / 20 columns: Time for destroy/create pair dropped from about 1260ms to about 150ms. Related to #2298, but does not really fix it as we are still slow if people are using `<content>`. Closes #2297
This commit is contained in:
@ -52,6 +52,13 @@ export class LightDom {
|
||||
|
||||
// Collects the Content directives from the view and all its child views
|
||||
private _collectAllContentTags(view: viewModule.DomView, acc: List<Content>): List<Content> {
|
||||
// Note: exiting early here is important as we call this function for every view
|
||||
// that is added, so we have O(n^2) runtime.
|
||||
// TODO(tbosch): fix the root problem, see
|
||||
// https://github.com/angular/angular/issues/2298
|
||||
if (view.proto.transitiveContentTagCount === 0) {
|
||||
return acc;
|
||||
}
|
||||
var contentTags = view.contentTags;
|
||||
var vcs = view.viewContainers;
|
||||
for (var i = 0; i < vcs.length; i++) {
|
||||
|
@ -25,10 +25,13 @@ export class DomProtoView {
|
||||
elementBinders: List<ElementBinder>;
|
||||
isTemplateElement: boolean;
|
||||
rootBindingOffset: number;
|
||||
// the number of content tags seen in this or any child proto view.
|
||||
transitiveContentTagCount: number;
|
||||
|
||||
constructor({elementBinders, element}) {
|
||||
constructor({elementBinders, element, transitiveContentTagCount}) {
|
||||
this.element = element;
|
||||
this.elementBinders = elementBinders;
|
||||
this.transitiveContentTagCount = transitiveContentTagCount;
|
||||
this.isTemplateElement = DOM.isTemplateElement(this.element);
|
||||
this.rootBindingOffset =
|
||||
(isPresent(this.element) && DOM.hasClass(this.element, NG_BINDING_CLASS)) ? 1 : 0;
|
||||
|
@ -54,6 +54,7 @@ export class ProtoViewBuilder {
|
||||
var renderElementBinders = [];
|
||||
|
||||
var apiElementBinders = [];
|
||||
var transitiveContentTagCount = 0;
|
||||
ListWrapper.forEach(this.elements, (ebb) => {
|
||||
var propertySetters = MapWrapper.create();
|
||||
var hostActions = MapWrapper.create();
|
||||
@ -82,6 +83,14 @@ export class ProtoViewBuilder {
|
||||
});
|
||||
|
||||
var nestedProtoView = isPresent(ebb.nestedProtoView) ? ebb.nestedProtoView.build() : null;
|
||||
var nestedRenderProtoView =
|
||||
isPresent(nestedProtoView) ? resolveInternalDomProtoView(nestedProtoView.render) : null;
|
||||
if (isPresent(nestedRenderProtoView)) {
|
||||
transitiveContentTagCount += nestedRenderProtoView.transitiveContentTagCount;
|
||||
}
|
||||
if (isPresent(ebb.contentTagSelector)) {
|
||||
transitiveContentTagCount++;
|
||||
}
|
||||
var parentIndex = isPresent(ebb.parent) ? ebb.parent.index : -1;
|
||||
ListWrapper.push(apiElementBinders, new api.ElementBinder({
|
||||
index: ebb.index,
|
||||
@ -112,8 +121,11 @@ export class ProtoViewBuilder {
|
||||
}));
|
||||
});
|
||||
return new api.ProtoViewDto({
|
||||
render: new DomProtoViewRef(
|
||||
new DomProtoView({element: this.rootElement, elementBinders: renderElementBinders})),
|
||||
render: new DomProtoViewRef(new DomProtoView({
|
||||
element: this.rootElement,
|
||||
elementBinders: renderElementBinders,
|
||||
transitiveContentTagCount: transitiveContentTagCount
|
||||
})),
|
||||
type: this.type,
|
||||
elementBinders: apiElementBinders,
|
||||
variableBindings: this.variableBindings
|
||||
|
Reference in New Issue
Block a user