Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 97fb86d

Browse files
P4AndrewKushnir
authored andcommitted
perf(core): set encapsulation to None for empty component styles (#57130)
Make it so that encapsulation for empty styles, styles containing only whitespace and comments, etc. is handled the same way as with no styles at all. Components without styles already have view encapsulation set to `None` to avoid generating unnecessary attributes for style scoping, like `_ngcontent-ng-c1` (#27175) If the component has an empty external styles file instead, the compiler would generate a component definition without the `styles` field, but still using the default encapsulation. This can result in runtime overhead if the developer forgets to delete the empty styles file generated automatically for new components by Angular CLI. Closes #16602 PR Close #57130
1 parent 1e50374 commit 97fb86d

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

‎packages/compiler/src/render3/view/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ export function compileComponentFromMetadata(
290290
let hasStyles = !!meta.externalStyles?.length;
291291
// e.g. `styles: [str1, str2]`
292292
if (meta.styles && meta.styles.length) {
293-
hasStyles = true;
294293
const styleValues =
295294
meta.encapsulation == core.ViewEncapsulation.Emulated
296295
? compileStyles(meta.styles, CONTENT_ATTR, HOST_ATTR)
@@ -303,6 +302,7 @@ export function compileComponentFromMetadata(
303302
}, [] as o.Expression[]);
304303

305304
if (styleNodes.length > 0) {
305+
hasStyles = true;
306306
definitionMap.set('styles', o.literalArr(styleNodes));
307307
}
308308
}

‎packages/core/test/acceptance/bootstrap_spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ describe('bootstrap', () => {
9292
) {
9393
@Component({
9494
selector: options.selector || 'my-app',
95-
styles: [''],
95+
// styles must be non-empty to trigger `ViewEncapsulation.Emulated`
96+
styles: 'span {color:red}',
9697
template: '<span>a b</span>',
9798
encapsulation: options.encapsulation,
9899
preserveWhitespaces: options.preserveWhitespaces,

‎packages/core/test/acceptance/component_spec.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ describe('component', () => {
145145
@Component({
146146
selector: 'encapsulated',
147147
encapsulation: ViewEncapsulation.Emulated,
148-
// styles array must contain a value (even empty) to trigger `ViewEncapsulation.Emulated`
149-
styles: [``],
148+
// styles must be non-empty to trigger `ViewEncapsulation.Emulated`
149+
styles: `:host {display: block}`,
150150
template: `foo<leaf></leaf>`,
151151
})
152152
class EncapsulatedComponent {}
@@ -182,9 +182,9 @@ describe('component', () => {
182182
});
183183

184184
it('should encapsulate host and children with different attributes', () => {
185-
// styles array must contain a value (even empty) to trigger `ViewEncapsulation.Emulated`
185+
// styles must be non-empty to trigger `ViewEncapsulation.Emulated`
186186
TestBed.overrideComponent(LeafComponent, {
187-
set: {encapsulation: ViewEncapsulation.Emulated, styles: [``]},
187+
set: {encapsulation: ViewEncapsulation.Emulated, styles: [`span {color:red}`]},
188188
});
189189
const fixture = TestBed.createComponent(EncapsulatedComponent);
190190
fixture.detectChanges();
@@ -198,6 +198,28 @@ describe('component', () => {
198198
}=""><span ${match[1].replace('_nghost', '_ngcontent')}="">bar</span></leaf></div>`,
199199
);
200200
});
201+
202+
it('should be off for a component with no styles', () => {
203+
TestBed.overrideComponent(EncapsulatedComponent, {
204+
set: {styles: undefined},
205+
});
206+
const fixture = TestBed.createComponent(EncapsulatedComponent);
207+
fixture.detectChanges();
208+
const html = fixture.nativeElement.outerHTML;
209+
expect(html).not.toContain('<encapsulated _nghost-');
210+
expect(html).not.toContain('<leaf _ngcontent-');
211+
});
212+
213+
it('should be off for a component with empty styles', () => {
214+
TestBed.overrideComponent(EncapsulatedComponent, {
215+
set: {styles: [` `, '', '/*comment*/']},
216+
});
217+
const fixture = TestBed.createComponent(EncapsulatedComponent);
218+
fixture.detectChanges();
219+
const html = fixture.nativeElement.outerHTML;
220+
expect(html).not.toContain('<encapsulated _nghost-');
221+
expect(html).not.toContain('<leaf _ngcontent-');
222+
});
201223
});
202224

203225
describe('view destruction', () => {

0 commit comments

Comments
 (0)