Книга: Angular 2 Cookbook
Назад: Configuring components to use explicit change detection with OnPush
Дальше: Configuring the Angular 2 Renderer to use web workers

Configuring ViewEncapsulation for maximum efficiency

Although it may sound clichéd, Angular 2 was built for the browsers of tomorrow. You can point to why this is the case in a large number of ways, but there is one way where this is extremely true: component encapsulation.

The ideal component model for Angular 2 is the one in which components are entirely sandboxed, save for the few pieces that are externally visible and modifiable. In this respect, it does a bang-up job, but even the most modern browsers limit its ability to strive for such efficacy. This is especially true in the realm of CSS styling.

Several features of Angular's component styling are especially important:

  • You are able to write styles that are guaranteed to be only applicable to a component
  • You can explicitly specify styles that should be inherited downward through the component tree
  • You can specify an encapsulation strategy on a piecewise basis

There are a number of interesting ways to accomplish an efficient component styling schema.

Note

The code, links, and a live example related to this recipe are available at .

Getting ready

Begin with a simple application component:

[src/app/app.component.ts]      import {Component} from '@angular/core';      @Component({     selector: 'app-root',     template: `       <h1>         {{title}}       </h1>     `,     styles: [`       h1 {          color: red;       }     `]   })   export class AppComponent {     title = 'app works!';   }   

How to do it...

Angular will default to not using ShadowDOM for components, as the majority of browsers do not support it to a satisfactory level. The next best thing, which it will default to, is to emulate this styling encapsulation by nesting your selectors. The preceding component is effectively the equivalent of the following:

[src/app/app.component.ts]      import {Component, ViewEncapsulation} from '@angular/core';      @Component({     selector: 'app-root',     template: `       <h1>         {{title}}       </h1>     `,     styles: [`       h1 {         color: red;       }     `],     encapsulation: ViewEncapsulation.Emulated   })   export class AppComponent {     title = 'app works!';   }   

Emulated styling encapsulation

How exactly does Angular perform this emulation? Look at the rendered application to find out. Your component will appear something like the following:

<app-root _nghost-mqf-1="">     <h1 _ngcontent-mqf-1="">       app works!     </h1>   </app-root>   

In the head of the document:

<style>     h1[_ngcontent-mqf-1] {       color: red;     }   </style>   

The picture should be a bit clearer now. Angular is assigning this component class (not an instance) a unique ID, and the styles defined for the global document will only be applicable to tags that have the matching attribute.

No styling encapsulation

If this encapsulation isn't necessary, you are free to use encapsulation: ViewEncapsulation.None. Angular will happily skip the unique ID assignment step for you, giving you a vanilla:

<app-root>     <h1>       app works!     </h1>   </app-root>   

In the head of the document:

<style>     h1 {       color: red;     }   </style>   

Native styling encapsulation

The best, most futuristic, and least supported method of going about this is to use ShadowDOM instances to go along with each component instance. This can be accomplished using encapsulation: ViewEncapsulation.Native. Now, your component will render:

<app-root>     #shadow-root       <style>         h1 {           color: red;         }       </style>       <h1>         app works!       </h1>   </app-root>   

How it works...

Angular is smart enough to recognize where it needs to put your styles and how to modify them to make them work for your component configuration:

  • For None and Emulated, styles go into the document head
  • For Native, styles go inline with the rendered component
  • For None and Native, no style modifications are needed
  • For Emulated, styles are restricted by attribute selectors

There's more...

An important consideration of ViewEncapsulation choices is CSS performance. It is well known and entirely intuitive that CSS styling is more efficient when it has to traverse a smaller part of the DOM and has to match using a simpler selector.

Emulating component encapsulation adds an attribute selector to each and every style that is defined for that component. At scale, it isn't hard to see how this can degrade performance. ShadowDOM elegantly solves this problem by offering unmodified styles inside a restricted piece of DOM. Its styles cannot escape but can be applied downward to other components. Furthermore, ShadowDOM components can be nested and strategically applied.

See also

  • Understanding and properly utilizing enableProdMode with pure and impure pipes describes how to take the training wheels off your application
  • Configuring components to use explicit change detection with OnPush describes how to manually control Angular's change detection process
Назад: Configuring components to use explicit change detection with OnPush
Дальше: Configuring the Angular 2 Renderer to use web workers

thank you
Flame
cant read the code since it is all on a single line. Also this comments section is russian
Rakuneque
DATA COLLECTION AND ANALYSIS Two reviewers extracted data and assessed methodological quality independently lasix torsemide conversion Many others were in that space already