SlideShare a Scribd company logo
Превышаем
скоростные
лимиты с Angular 2
Алексей Охрименко - IPONWEB
Алексей
Охрименко
Twitter: @Ai_boy
IPONWEB
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
IPONWEB
RTB
DSP
SSP
8
последствия превышения
скорости (в реальной жизни)
последствия
превышения
скорости*
* - поищите в Google Image - 4-ый результат
Всегда
успеете…
А где тогда скорость превышать?
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Angular 2, Angular 2…
нас и [НАШ_FRAMEWORK]
неплохо кормит
Превышаем скоростные лимиты с Angular 2
А что значит «скорость»?
Скорость
загрузки
Скорость
загрузки
Размер
Скорость
загрузки
Размер
LazyLoading
Скорость
загрузки
Скорость работы
Размер
LazyLoading
Скорость
загрузки
Скорость работы
Размер
LazyLoading
Обьем работы
Скорость
загрузки
Скорость работы
Размер
LazyLoading
Обьем работы Производительность
Скорость
загрузки
Скорость работы
Размер
LazyLoading
Обьем работы Производительность
Память
Скорость
загрузки
Скорость работы
Размер
LazyLoading
Обьем работы
Многопоточность
Производительность
Память
Скорость работы
Обьем работы
Многопоточность
Производительность
Память
Скорость
загрузки
Размер
LazyLoading
Скорость работы
https://github.com/krausest/js-framework-benchmark
https://github.com/mathieuancelin/js-repaint-perfs
Превышаем скоростные лимиты с Angular 2
Кол-во перерисовок в секунду (больше лучше)
Angular 1
Angular 2
React
Elm
0 9 18 27 36
Наша цель … 90 RR
Кол-во перерисовок в секунду (больше лучше)
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
Старая версия Angular 2
Alpha 44
Alpha 44 —> v2.1.2
Alpha 44
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
v2.1.2
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
v2.1.2
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
На самом деле все просто…
Angular 2 Performance Checklist
import {enableProdMode} from '@angular/core';
enableProdMode();
300% в Edge
enableProdMode()
Alpha 44
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
v2.1.2 + enableProdMod()
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
function getData(keepIdentity) {
var oldData = data;
if (!keepIdentity) { // reset for each tick
data = [];
for (var i = 1; i <= ENV.rows; i++) {
data.push({ … });
data.push({ … });
}
}
}
@Page({
template: `
<div
*ngFor="let post of posts;trackBy:identify">
{{post.data}}
</div>
`
})
export class SomeConponent {
identify(index,item){
return post.id
}
}
@Page({
template: `
<div
*ngFor="let post of posts;trackBy:identify">
{{post.data}}
</div>
`
})
export class SomeConponent {
identify(index,item){
return post.id
}
}
v2.1.2 + enableProdMod()
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
trackBy
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
AOT
Ahead Of Time template compilation
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Angular CLI
ng serve ——aot
ng build ——aot
trackBy
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
AOT
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
WebWorkers
import {bootstrapWorkerUi} from '@angular/platform-webworker';
import {enableProdMode} from '@angular/core';
export function main() {
enableProdMode();
bootstrapWorkerUi('loader.js');
}
import {bootstrapWorkerUi} from '@angular/platform-webworker';
import {enableProdMode} from '@angular/core';
export function main() {
enableProdMode();
bootstrapWorkerUi('loader.js');
}
@NgModule({
imports: [WorkerAppModule],
bootstrap: [AppComponent],
declarations: [AppComponent]
})
class WebWorkerModule {}
export function main() {
enableProdMode();
platformWorkerAppDynamic().bootstrapModule(WebWorkerModule);
}
@NgModule({
imports: [WorkerAppModule],
bootstrap: [AppComponent],
declarations: [AppComponent]
})
class WebWorkerModule {}
export function main() {
enableProdMode();
platformWorkerAppDynamic().bootstrapModule(WebWorkerModule);
}
AOT
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
webWorkers
Angular 2
Target
0 10 20 30 40 50 60 70 80 90
Превышаем скоростные лимиты с Angular 2
Кол-во перерисовок в секунду (больше лучше)
Angular 1
Angular 2
React
Elm
0 10 20 30 40 50 60 70 80 90
Еще раз
• enableProd()
• trackBy
• AOT
• WebWorkers
Заглянем под капот
Scott
Hanselman
ZoneJs
Превышаем скоростные лимиты с Angular 2
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Превышаем скоростные лимиты с Angular 2
process.on('uncaughtException', (err) => {
console.log(`Caught exception: ${err}`);
});
Превышаем скоростные лимиты с Angular 2
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone);
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone);
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone);
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone);
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone); // TRUE
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone);
}
setTimeout(someCallback, 0);
Zone.current.fork({}).run(function () {
Zone.current.inTheZone = true;
setTimeout(someCallback, 0);
});
function someCallback() {
console.log(Zone.current.inTheZone); // FALSE
}
setTimeout(someCallback, 0);
Change Detection
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
// very simplified version of actual source
class ApplicationRef {
changeDetectorRefs:ChangeDetectorRef[] = [];
constructor(private zone: NgZone) {
this.zone.onTurnDone
.subscribe(() => {
this.zone.run(() => this.tick()
});
}
tick() {
this.changeDetectorRefs
.forEach((ref) => ref.detectChanges());
}
}
// very simplified version of actual source
class ApplicationRef {
changeDetectorRefs:ChangeDetectorRef[] = [];
constructor(private zone: NgZone) {
this.zone.onTurnDone
.subscribe(() => {
this.zone.run(() => this.tick()
});
}
tick() {
this.changeDetectorRefs
.forEach((ref) => ref.detectChanges());
}
}
// very simplified version of actual source
class ApplicationRef {
changeDetectorRefs:ChangeDetectorRef[] = [];
constructor(private zone: NgZone) {
this.zone.onTurnDone
.subscribe(() => {
this.zone.run(() => this.tick()
});
}
tick() {
this.changeDetectorRefs
.forEach((ref) => ref.detectChanges());
}
}
// very simplified version of actual source
class ApplicationRef {
changeDetectorRefs:ChangeDetectorRef[] = [];
constructor(private zone: NgZone) {
this.zone.onTurnDone
.subscribe(() => {
this.zone.run(() => this.tick()
});
}
tick() {
this.changeDetectorRefs
.forEach((ref) => ref.detectChanges());
}
}
Превышаем скоростные лимиты с Angular 2
@Component({
template: '<v-card [vData]="vData"></v-card>'
})
class VCardApp {
constructor() {
this.vData = {
name: 'Christoph Burgdorf',
email: 'christoph@thoughtram.io'
}
}
changeData() {
this.vData.name = 'Pascal Precht';
}
}
@Component({
template: `
<h2>{{vData.name}}</h2>
<span>{{vData.email}}</span>
`
})
class VCardCmp {
@Input() vData;
}
@Component({
template: '<v-card [vData]="vData"></v-card>'
})
class VCardApp {
constructor() {
this.vData = {
name: 'Christoph Burgdorf',
email: 'christoph@thoughtram.io'
}
}
changeData() {
this.vData = { name: 'Pascal Precht' };
}
}
@Component({
template: `
<h2>{{vData.name}}</h2>
<span>{{vData.email}}</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class VCardCmp {
@Input() vData;
}
Превышаем скоростные лимиты с Angular 2
Управляем Zone и CD
constructor(private zone: NgZone) {}
processOutsideAngularZone() {
this.progress = 0;
this.zone.runOutsideAngular(() => {
this.increaseProgress(() => {
this.zone.run(() => {
console.log('Outside Done!');
});
});
});
}
processOutsideAngularZone() {
this.progress = 0;
this.zone.runOutsideAngular(() => {
this.increaseProgress(() => {
this.zone.run(() => {
console.log('Outside Done!');
});
});
});
}
constructor(private cd: ChangeDetectorRef) {}
ngOnInit() {
this.addItemStream.subscribe(() => {
this.counter++; // application state changed
this.cd.markForCheck(); // marks path
})
}
}
А можно как-то попроще?
Redux
ng2-redux
ngrx/store
Mobx
ng2-mobx
Превышаем скоростные лимиты с Angular 2
Улучшаем Perceived Performance
•Увеличивая реальную производительность
Улучшаем Perceived Performance
•Увеличивая реальную производительность
•Замедляя реальную производительность
Улучшаем Perceived Performance
•Увеличивая реальную производительность
•Замедляя реальную производительность
•Грамотно перераспределяя нагрузку и
ресурсы
Превышаем скоростные лимиты с Angular 2
FRP
functional reactive programming
this.form.valueChanges
.filter((value) => this.form.valid)
.switchMap((value) => {
return http.post(‘/api’, value)
});
this.form.valueChanges
.debounce(500)
.filter((value) => this.form.valid)
.switchMap((value) => {
return http.post(‘/api’, value)
});
this.form.valueChanges
.debounce(500)
.distinctUntilChanged()
.filter((value) => this.form.valid)
.switchMap((value) => {
return http.post(‘/api’, value)
});
this.form.valueChanges
.debounce(500)
.distinctUntilChanged()
.filter((value) => this.form.valid)
.switchMap((value) => {
return http.post(‘/api’, value)
}).retryWhen(attempts =>
attempts
.zip(Observable.range(1, 3), (_, i) => i)
.flatMap((i: number) => {
return Observable.timer(i * 1000);
})
))
Превышаем скоростные лимиты с Angular 2
Алексей
Охрименко
Twitter: @Ai_boy
IPONWEB
http://bit.ly/2eMOBjm

More Related Content

What's hot (20)

PPTX
Асинхронность и сопрограммы
Platonov Sergey
 
PDF
«Как перестать отлаживать асинхронные вызовы и начать жить»​
FDConf
 
PDF
Joker 2016 - Bytecode 101
Anton Arhipov
 
PDF
Тестируй это / Виктор Русакович (GP Solutions)
Ontico
 
PDF
Контроль качества верстки или как начать делать Makeup
Timophy Chaptykov
 
PDF
JPoint 2016 - Bytecode
Anton Arhipov
 
PPTX
Selenium: начало работы
Paul Stashevsky
 
PPTX
Особенности разработки API / Всеволод Шмыров (Яндекс)
Ontico
 
PPTX
XPath локаторы в Selenium WebDriver
Илья Кожухов
 
PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
zfconfua
 
PDF
RDSDataSource: Promises
RAMBLER&Co
 
PDF
JPoint 2015 - Javassist на службе Java-разработчика
Anton Arhipov
 
PDF
DI в C++ тонкости и нюансы
Platonov Sergey
 
PDF
Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Yulia Tsisyk
 
PDF
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Ontico
 
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Sergey Platonov
 
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Sergey Platonov
 
PDF
Wild Async .NET world: AID Kit for boy-scouts
HYS Enterprise
 
PDF
Григорий Демченко — Асинхронное программирование и сопрограммы
Yandex
 
PDF
Цена ошибки
Platonov Sergey
 
Асинхронность и сопрограммы
Platonov Sergey
 
«Как перестать отлаживать асинхронные вызовы и начать жить»​
FDConf
 
Joker 2016 - Bytecode 101
Anton Arhipov
 
Тестируй это / Виктор Русакович (GP Solutions)
Ontico
 
Контроль качества верстки или как начать делать Makeup
Timophy Chaptykov
 
JPoint 2016 - Bytecode
Anton Arhipov
 
Selenium: начало работы
Paul Stashevsky
 
Особенности разработки API / Всеволод Шмыров (Яндекс)
Ontico
 
XPath локаторы в Selenium WebDriver
Илья Кожухов
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
zfconfua
 
RDSDataSource: Promises
RAMBLER&Co
 
JPoint 2015 - Javassist на службе Java-разработчика
Anton Arhipov
 
DI в C++ тонкости и нюансы
Platonov Sergey
 
Сенцов Сергей "Приемы оптимизаций Desktop приложений"
Yulia Tsisyk
 
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Ontico
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Sergey Platonov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Sergey Platonov
 
Wild Async .NET world: AID Kit for boy-scouts
HYS Enterprise
 
Григорий Демченко — Асинхронное программирование и сопрограммы
Yandex
 
Цена ошибки
Platonov Sergey
 

Viewers also liked (9)

DOCX
Handoutmodyul9
Juriz de Mesa
 
PPTX
Advanced java online training
Glory IT Technologies Pvt. Ltd.
 
PPT
Alkanes
srinidhimateti
 
DOCX
Handoutmodyul10 -Para sa Edukasyon sa Pagpapakatao -10
Juriz de Mesa
 
PPTX
Alomorp ng morpema requirements by Maribeth Lactaotao
jethrod13
 
PDF
Even more java script best practices
ChengHui Weng
 
PPTX
Appropriateness of assessment method
Jhizelle Almonte
 
PPTX
076 Modular Construction
Dr Fereidoun Dejahang
 
PDF
Salik sa Pagkakaroon ng Motibasyon at Determinasyon sa Napiling Kurso ng mga ...
JM Esguerra
 
Handoutmodyul9
Juriz de Mesa
 
Advanced java online training
Glory IT Technologies Pvt. Ltd.
 
Handoutmodyul10 -Para sa Edukasyon sa Pagpapakatao -10
Juriz de Mesa
 
Alomorp ng morpema requirements by Maribeth Lactaotao
jethrod13
 
Even more java script best practices
ChengHui Weng
 
Appropriateness of assessment method
Jhizelle Almonte
 
076 Modular Construction
Dr Fereidoun Dejahang
 
Salik sa Pagkakaroon ng Motibasyon at Determinasyon sa Napiling Kurso ng mga ...
JM Esguerra
 
Ad

Превышаем скоростные лимиты с Angular 2