Angular 2
The Shiny Parts
Maxim Salnikov
@webmaxru
-
Google Developer Expert in Angular
-
AngularJS Oslo Meetup organizer
-
Mobileera.Rocks conf organizer
Products from the future
UI Engineer at ForgeRock
Google Developer Experts
Google Experts are a global network of experienced product strategists, designers, developers and marketing professionals actively supporting developers, startups and companies changing the world through web and mobile applications.
The Pale Parts
2 years of development
Not backwards compatible
Bre
a
king
ch
ange
s
Flexibility
ES
ES2015
ES2016
TS
Versatility
Performance
Performance
Ahead of Time compilation
Change detection
Server-side rendering
Web Workers
Compiler
A compiler is a computer program that transforms source code written in a programming language into another computer language [...] The most common reason for converting source code is to create an executable program.
JIT
Just-in-time (JIT) compilation, also known as dynamic translation, is compilation done during execution of a program – at run time...
Application
Compiler
AOT
Ahead-of-time (AOT) compilation is the act of compiling a high-level programming language, into a native machine code with the intention of executing the resulting binary file natively. AOT produces machine optimized code...
Application
Compiler
Machine optimized?
createInternal(rootSelector:string):import4.AppElement {
const parentRenderNode:any = this.renderer.createViewRoot(this.declarationAppElement.nativeElement);
this._el_0 = this.renderer.createElement(parentRenderNode,'md-toolbar',this.debug(0,0,0));
this.renderer.setElementAttribute(this._el_0,'class','extend-toolbar');
this._appEl_0 = new import4.AppElement(0,(null as any),this,this._el_0);
var compView_0:any = import14.viewFactory_MdToolbar0(this.viewUtils,this.injector(0),this._appEl_0);
this._MdToolbar_0_4 = new import12.MdToolbar(new import15.ElementRef(this._el_0),this.renderer);
this._appEl_0.initComponent(this._MdToolbar_0_4,[],compView_0);
this._text_1 = this.renderer.createText((null as any),'\n ',this.debug(1,0,35));
this._el_2 = this.renderer.createElement((null as any),'span',this.debug(2,1,2));
this._text_3 = this.renderer.createText(this._el_2,'\n ',this.debug(3,1,8));
this._el_4 = this.renderer.createElement(this._el_2,'a',this.debug(4,2,4));
this.renderer.setElementAttribute(this._el_4,'href','#/home');
this._text_5 = this.renderer.createText(this._el_4,'\n ',this.debug(5,2,21));
this._el_6 = this.renderer.createElement(this._el_4,'img',this.debug(6,3,6));
this.renderer.setElementAttribute(this._el_6,'alt','Sfeir');
this.renderer.setElementAttribute(this._el_6,'aria-label','foobar');
this.renderer.setElementAttribute(this._el_6,'src','assets/images/logo-foo.svg');
this._text_7 = this.renderer.createText(this._el_4,'\n ',this.debug(7,3,77));
this._text_8 = this.renderer.createText(this._el_2,'\n ',this.debug(8,4,8));
this._text_9 = this.renderer.createText((null as any),'\n\n ',this.debug(9,5,9));
this._el_10 = this.renderer.createElement((null as any),'span',this.debug(10,7,2));
this.renderer.setElementAttribute(this._el_10,'class','flex');
this._text_11 = this.renderer.createText((null as any),'\n\n ',this.debug(11,7,28));
this._el_12 = this.renderer.createElement((null as any),'span',this.debug(12,9,2));
this._text_13 = this.renderer.createText(this._el_12,'\n ',this.debug(13,9,8));
this._el_14 = this.renderer.createElement(this._el_12,'a',this.debug(14,10,4));
this.renderer.setElementAttribute(this._el_14,'href','#/locator');
this._text_15 = this.renderer.createText(this._el_14,'Maps',this.debug(15,10,24));
this._text_16 = this.renderer.createText(this._el_12,'\n ',this.debug(16,10,32));
this._el_17 = this.renderer.createElement(this._el_12,'a',this.debug(17,11,4));
this.renderer.setElementAttribute(this._el_17,'href','#/app');
this._text_18 = this.renderer.createText(this._el_17,'List',this.debug(18,11,23));
this._text_19 = this.renderer.createText(this._el_12,'\n ',this.debug(19,11,31));
this._text_20 = this.renderer.createText((null as any),'\n',this.debug(20,12,9));
Benefits?
Application
Smaller bundle size
Fewer async requests
Faster rendering
Benefits?
Tree Shaking!
A technique to "shake" off unused code, thus shrinking the size of the deployed application
Drawbacks?
Needs compilation context
@NgModule
@NgModule({
imports: [
BrowserModule, MdModule,
HttpModule, RoutesModule...
],
declarations: [
HomeComponent, ShinyComponent...
],
providers: [ ShinyService ],
bootstrap: [ AppComponent ]
})
Unified codebase
// The browser platform with a compiler
import {
platformBrowserDynamic
} from '@angular/platform-browser-dynamic';
// The app module
import { AppModule } from './app.module';
// Compile (JIT) and launch the module
platformBrowserDynamic().bootstrapModule(
AppModule
);
// The browser platform with a compiler
import {
platformBrowser
} from '@angular/platform-browser';
// The generated app factory (AOT)
import {
AppModuleNgFactory
} from './app.module.ngfactory';
// Launch with the app module factory.
platformBrowser().bootstrapModuleFactory(
AppModuleNgFactory
);
Dev
Prod
Some tools needed...
$ npm install \
@angular/compiler-cli \
@angular/platform-server \
@angular/compiler \
typescript@next --save
$ ./node_modules/.bin/ngc -p tsconfig.aot.json
$ # generates app.module.ngfactory.ts
$ # generates app.component.ngfactory.ts
$ # generates app.component.css.shim.ts
$ # generates ...
Change detection
The change detection graph is a directed tree. As a result: 3-10x faster than Angular 1.x
An Angular 2 app is a reactive system
The change detection system propagates bindings from the root to leaves
Strategies
changeDetection: ChangeDetectionStrategy.Default
Strategies
changeDetection: ChangeDetectionStrategy.Default
Strategies
changeDetection: ChangeDetectionStrategy.OnPush
Strategies
changeDetection: ChangeDetectionStrategy.OnPush
Under the hood
Scalability
Scalability
Lazy-loading
Scalable communication layer
Reusability
Unfortunately the ''C'' in CSS is ''cascade"
Ideally the ''C'' in CSS would be ''component"
Shadow DOM fixes CSS and DOM. It introduces scoped styles to the web platform.
ViewEncapsulation.Native
ViewEncapsulation.Emulated
<!-- Original DOM -->
<hero-details>
<h2>Mister Fantastic</h2>
<hero-team>
<h3>Team</h3>
</hero-team>
</hero-detail>
<!-- Original CSS -->
hero-details {
display: block;
border: 1px solid black;
}
h3 {
background-color: white;
border: 1px solid #777;
}
<!-- Rendered DOM -->
<hero-details _nghost-pmm-5>
<h2 _ngcontent-pmm-5>Mister Fantastic</h2>
<hero-team _ngcontent-pmm-5 _nghost-pmm-6>
<h3 _ngcontent-pmm-6>Team</h3>
</hero-team>
</hero-detail>
<!-- Rendered CSS -->
[_nghost-pmm-5] {
display: block;
border: 1px solid black;
}
h3[_ngcontent-pmm-6] {
background-color: white;
border: 1px solid #777;
}
Convenience
CLI
npm install -g angular-cli
ng new my-shiny-app cd my-shiny-app
ng serve
ng generate component my-shiny-component ng g component my-shiny-component
ng g class my-shiny-class ng g service my-shiny-service
ng build --dev ng build --prod
ng test ng e2e
ng github-pages:deploy --message "Go!"
On the way back
Generating routes
Support for offline applications
Mobile Toolkit
Service Workers
App Shell
Manifest generation
Workflow built into CLI
Þakka þér!
@webmaxru
Maxim Salnikov
Angular 2. The Shiny Parts.
By Maxim Salnikov
Angular 2. The Shiny Parts.
1. Intro aka what is “shiny” and why it makes us awesome 2. AOT Compilation - improve performance 3. Change Detection - sane data flow 4. View Encapsulation - build portable components 5. Hierarchical Dependency Injection - improve composability 6. Observables - reduce complexity 7. Angular CLI - convenience 8. Outro aka now go be awesome
- 2,662