perf(ivy): attempt rendering initial styling only if present (#32979)
PR Close #32979
This commit is contained in:
parent
e6881b5b42
commit
60047037a3
|
@ -152,10 +152,6 @@ export function getOrCreateNodeInjectorForNode(
|
|||
insertBloom(tView.data, tNode); // foundation for node bloom
|
||||
insertBloom(hostView, null); // foundation for cumulative bloom
|
||||
insertBloom(tView.blueprint, null);
|
||||
|
||||
ngDevMode && assertEqual(
|
||||
tNode.flags === 0 || tNode.flags === TNodeFlags.isComponentHost, true,
|
||||
'expected tNode.flags to not be initialized');
|
||||
}
|
||||
|
||||
const parentLoc = getParentInjectorLocation(tNode, hostView);
|
||||
|
|
|
@ -10,7 +10,7 @@ import {assertDataInRange, assertDefined, assertEqual} from '../../util/assert';
|
|||
import {assertHasParent} from '../assert';
|
||||
import {attachPatchData} from '../context_discovery';
|
||||
import {registerPostOrderHooks} from '../hooks';
|
||||
import {TAttributes, TNodeType} from '../interfaces/node';
|
||||
import {TAttributes, TNodeFlags, TNodeType} from '../interfaces/node';
|
||||
import {RElement} from '../interfaces/renderer';
|
||||
import {StylingMapArray, TStylingContext} from '../interfaces/styling';
|
||||
import {isContentQueryHost, isDirectiveHost} from '../interfaces/type_checks';
|
||||
|
@ -64,7 +64,9 @@ export function ɵɵelementStart(
|
|||
}
|
||||
}
|
||||
|
||||
renderInitialStyling(renderer, native, tNode);
|
||||
if ((tNode.flags & TNodeFlags.hasInitialStyling) === TNodeFlags.hasInitialStyling) {
|
||||
renderInitialStyling(renderer, native, tNode);
|
||||
}
|
||||
|
||||
appendChild(native, tNode, lView);
|
||||
|
||||
|
|
|
@ -162,6 +162,7 @@ export const TNodeConstructor = class TNode implements ITNode {
|
|||
if (this.flags & TNodeFlags.hasClassInput) flags.push('TNodeFlags.hasClassInput');
|
||||
if (this.flags & TNodeFlags.hasContentQuery) flags.push('TNodeFlags.hasContentQuery');
|
||||
if (this.flags & TNodeFlags.hasStyleInput) flags.push('TNodeFlags.hasStyleInput');
|
||||
if (this.flags & TNodeFlags.hasInitialStyling) flags.push('TNodeFlags.hasInitialStyling');
|
||||
if (this.flags & TNodeFlags.isComponentHost) flags.push('TNodeFlags.isComponentHost');
|
||||
if (this.flags & TNodeFlags.isDirectiveHost) flags.push('TNodeFlags.isDirectiveHost');
|
||||
if (this.flags & TNodeFlags.isDetached) flags.push('TNodeFlags.isDetached');
|
||||
|
|
|
@ -1232,7 +1232,7 @@ function findDirectiveMatches(
|
|||
*/
|
||||
export function markAsComponentHost(tView: TView, hostTNode: TNode): void {
|
||||
ngDevMode && assertFirstTemplatePass(tView);
|
||||
hostTNode.flags = TNodeFlags.isComponentHost;
|
||||
hostTNode.flags |= TNodeFlags.isComponentHost;
|
||||
(tView.components || (tView.components = ngDevMode ? new TViewComponents() : [
|
||||
])).push(hostTNode.index);
|
||||
}
|
||||
|
@ -1279,16 +1279,11 @@ function saveNameToExportMap(
|
|||
* @param index the initial index
|
||||
*/
|
||||
export function initNodeFlags(tNode: TNode, index: number, numberOfDirectives: number) {
|
||||
const flags = tNode.flags;
|
||||
ngDevMode && assertEqual(
|
||||
flags === 0 || flags === TNodeFlags.isComponentHost, true,
|
||||
'expected node flags to not be initialized');
|
||||
|
||||
ngDevMode && assertNotEqual(
|
||||
numberOfDirectives, tNode.directiveEnd - tNode.directiveStart,
|
||||
'Reached the max number of directives');
|
||||
tNode.flags |= TNodeFlags.isDirectiveHost;
|
||||
// When the first directive is created on a node, save the index
|
||||
tNode.flags = (flags & TNodeFlags.isComponentHost) | TNodeFlags.isDirectiveHost;
|
||||
tNode.directiveStart = index;
|
||||
tNode.directiveEnd = index + numberOfDirectives;
|
||||
tNode.providerIndexes = index;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import {SafeValue} from '../../sanitization/bypass';
|
||||
import {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
|
||||
import {setInputsForProperty} from '../instructions/shared';
|
||||
import {AttributeMarker, TAttributes, TNode, TNodeType} from '../interfaces/node';
|
||||
import {AttributeMarker, TAttributes, TNode, TNodeFlags, TNodeType} from '../interfaces/node';
|
||||
import {RElement} from '../interfaces/renderer';
|
||||
import {StylingMapArray, StylingMapArrayIndex, TStylingContext} from '../interfaces/styling';
|
||||
import {BINDING_INDEX, LView, RENDERER} from '../interfaces/view';
|
||||
|
@ -474,6 +474,10 @@ export function registerInitialStylingOnTNode(
|
|||
updateRawValueOnContext(tNode.styles, stylingMapToString(styles, false));
|
||||
}
|
||||
|
||||
if (hasAdditionalInitialStyling) {
|
||||
tNode.flags |= TNodeFlags.hasInitialStyling;
|
||||
}
|
||||
|
||||
return hasAdditionalInitialStyling;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,8 +65,11 @@ export const enum TNodeFlags {
|
|||
/** This bit is set if the node has any "style" inputs */
|
||||
hasStyleInput = 0b00100000,
|
||||
|
||||
/** This bit is set if the node has initial styling */
|
||||
hasInitialStyling = 0b01000000,
|
||||
|
||||
/** This bit is set if the node has been detached by i18n */
|
||||
isDetached = 0b01000000,
|
||||
isDetached = 0b10000000,
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -113,6 +113,34 @@ describe('styling', () => {
|
|||
expect(outer.textContent.trim()).toEqual('outer');
|
||||
});
|
||||
|
||||
it('should render initial styling for repeated nodes that a component host', () => {
|
||||
@Component({
|
||||
selector: '[comp]',
|
||||
template: '',
|
||||
})
|
||||
class Comp {
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<ng-template ngFor [ngForOf]="items" let-item>
|
||||
<p comp class="a">A</p>
|
||||
</ng-template>
|
||||
`
|
||||
})
|
||||
class App {
|
||||
items = [1, 2, 3];
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [App, Comp],
|
||||
});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.debugElement.queryAll(By.css('.a')).length).toBe(3);
|
||||
});
|
||||
|
||||
it('should do nothing for empty style bindings', () => {
|
||||
@Component({template: '<div [style.color]></div>'})
|
||||
class App {
|
||||
|
|
Loading…
Reference in New Issue