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

123
Превышаем скоростные лимиты с Angular 2 Алексей Охрименко IPONWEB 1 #rtb_techday

Upload: oleksii-okhrymenko

Post on 14-Apr-2017

66 views

Category:

Software


0 download

TRANSCRIPT

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

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

Алексей Охрименко

IPONWEB

1

#rtb_techday

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

2

#rtb_techday

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

3

#rtb_techday

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

4

#rtb_techday

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

5

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

Алексей Охрименко

Twitter: @Ai_boy

6

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

7

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

IPONWEB

RTBDSPSSP

8

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

последствия превышения скорости (в реальной

жизни)

9

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

последствия превышения скорости*

* - поищите в Google Image - 4-ый результат

10

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

Всегда успеете…

11

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

А где тогда скорость превышать?

12

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

13

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

14

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

Angular 2

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

16

import { Component } from '@angular/core';

@Component({ moduleId: module.id, selector: 'project-name-app', template: ` <h1 (click)='onClick()'> {{title}} </h1> `, styleUrls: ['project-name.component.css'] }) export class PROJECTNAMEAppComponent { title = 'project-name works!'; }

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

17

import { Component } from '@angular/core';

@Component({ moduleId: module.id, selector: 'project-name-app', template: ` <h1 (click)='onClick()'> {{title}} </h1> `, styleUrls: ['project-name.component.css'] }) export class PROJECTNAMEAppComponent { title = 'project-name works!'; }

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

18

import { Component } from '@angular/core';

@Component({ moduleId: module.id, selector: 'project-name-app', template: ` <h1 (click)='onClick()'> {{title}} </h1> `, styleUrls: ['project-name.component.css'] }) export class PROJECTNAMEAppComponent { title = 'project-name works!'; }

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

Angular 2, Angular 2… нас и [НАШ_FRAMEWORK]

неплохо кормит

19

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

20

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

А что значит «скорость»?

21

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

Скорость загрузки

22

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

Скорость загрузки

Размер

23

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

Скорость загрузки

Размер

LazyLoading

24

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

25

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

Обьем работы

26

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

Обьем работы Производительность

27

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

Обьем работы Производительность

Память

28

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

Обьем работы

Многопоточность

Производительность

Память

29

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

Скорость загрузки

Скорость работы

Размер

LazyLoading

Обьем работы

Многопоточность

Производительность

Память

30

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

Скорость работы

31

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

https://github.com/krausest/js-framework-benchmark

https://github.com/mathieuancelin/js-repaint-perfs

32

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

33

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

Кол-во перерисовок в секунду (больше лучше)

Angular 1

Angular 2

React

Elm

0 9 18 27 36

34

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

Наша цель … 90 RR

35

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

Кол-во перерисовок в секунду (больше лучше)

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

36

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

Старая версия Angular 2

37

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

Alpha 44

38

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

Alpha 44 —> v2.1.2

39

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

Alpha 44

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

40

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

v2.1.2

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

41

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

v2.1.2

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

42

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

На самом деле все просто…

43

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

Angular 2 Performance Checklist

44

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

import {enableProdMode} from '@angular/core';

enableProdMode();

45

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

300% в EdgeenableProdMode()

46

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

Alpha 44

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

47

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

v2.1.2 + enableProdMod()

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

48

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

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({ … }); } } }

49

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

@Page({ template: ` <div *ngFor="let post of posts;trackBy:identify"> {{post.data}} </div> ` }) export class SomeConponent { identify(index,item){ return post.id } }

50

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

@Page({ template: ` <div *ngFor="let post of posts;trackBy:identify"> {{post.data}} </div> ` }) export class SomeConponent { identify(index,item){ return post.id } }

51

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

v2.1.2 + enableProdMod()

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

52

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

trackBy

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

53

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

AOTAhead Of Time template compilation

54

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

55

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

56

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

Angular CLI

ng serve ——aotng build ——aot

57

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

trackBy

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

58

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

AOT

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

59

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

WebWorkers

60

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

import {bootstrapWorkerUi} from '@angular/platform-webworker'; import {enableProdMode} from '@angular/core';

export function main() { enableProdMode(); bootstrapWorkerUi('loader.js'); }

61

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

import {bootstrapWorkerUi} from '@angular/platform-webworker'; import {enableProdMode} from '@angular/core';

export function main() { enableProdMode(); bootstrapWorkerUi('loader.js'); }

62

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

@NgModule({ imports: [WorkerAppModule], bootstrap: [AppComponent], declarations: [AppComponent] }) class WebWorkerModule {}

export function main() { enableProdMode(); platformWorkerAppDynamic().bootstrapModule(WebWorkerModule); }

63

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

@NgModule({ imports: [WorkerAppModule], bootstrap: [AppComponent], declarations: [AppComponent] }) class WebWorkerModule {}

export function main() { enableProdMode(); platformWorkerAppDynamic().bootstrapModule(WebWorkerModule); }

64

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

AOT

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

65

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

webWorkers

Angular 2

Target

0 10 20 30 40 50 60 70 80 90

66

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

67

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

Кол-во перерисовок в секунду (больше лучше)

Angular 1

Angular 2

React

Elm

0 10 20 30 40 50 60 70 80 90

68

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

Еще раз• enableProd() • trackBy • AOT • WebWorkers

69

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

Заглянем под капот

70

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

Scott Hanselman

71

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

ZoneJs

72

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

73

Page 74: Превышаем скоросные лимиты с 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}/`); });

74

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

75

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

process.on('uncaughtException', (err) => { console.log(`Caught exception: ${err}`); });

76

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

77

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone); }

setTimeout(someCallback, 0);

78

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone); }

setTimeout(someCallback, 0);

79

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone); }

setTimeout(someCallback, 0);

80

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone); }

setTimeout(someCallback, 0);

81

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone);//TRUE }

setTimeout(someCallback, 0);

82

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone); }

setTimeout(someCallback, 0);

83

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

Zone.current.fork({}).run(function () { Zone.current.inTheZone = true; setTimeout(someCallback, 0); });

function someCallback() { console.log(Zone.current.inTheZone);//FALSE }

setTimeout(someCallback, 0);

84

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

Change Detection

85

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

86

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

87

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

88

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

89

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

90

Page 91: Превышаем скоросные лимиты с 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()); } }

91

Page 92: Превышаем скоросные лимиты с 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()); } }

92

Page 93: Превышаем скоросные лимиты с 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()); } }

93

Page 94: Превышаем скоросные лимиты с 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()); } }

94

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

95

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

@Component({ template: '<v-card [vData]="vData"></v-card>' }) class VCardApp {

constructor() { this.vData = { name: 'Christoph Burgdorf', email: '[email protected]' } }

changeData() { this.vData.name = 'Pascal Precht'; } }

96

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

@Component({ template: ` <h2>{{vData.name}}</h2> <span>{{vData.email}}</span> ` }) class VCardCmp { @Input() vData; }

97

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

@Component({ template: '<v-card [vData]="vData"></v-card>' }) class VCardApp {

constructor() { this.vData = { name: 'Christoph Burgdorf', email: '[email protected]' } }

changeData() { this.vData = { name: 'Pascal Precht' }; } }

98

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

@Component({ template: ` <h2>{{vData.name}}</h2> <span>{{vData.email}}</span> `, changeDetection: ChangeDetectionStrategy.OnPush }) class VCardCmp { @Input() vData; }

99

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

100

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

Управляем Zone и CD

101

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

constructor(private zone: NgZone) {}

102

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

processOutsideAngularZone() { this.progress = 0; this.zone.runOutsideAngular(() => { this.increaseProgress(() => { this.zone.run(() => { console.log('Outside Done!'); }); }); }); }

103

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

processOutsideAngularZone() { this.progress = 0; this.zone.runOutsideAngular(() => { this.increaseProgress(() => { this.zone.run(() => { console.log('Outside Done!'); }); }); }); }

104

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

constructor(private cd: ChangeDetectorRef) {}

105

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

ngOnInit() { this.addItemStream.subscribe(() => { this.counter++; // application state changed this.cd.markForCheck(); // marks path }) } }

106

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

А можно как-то попроще?

107

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

Redux

108

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

ng2-redux ngrx/store

109

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

Mobx

110

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

ng2-mobx

111

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

112

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

Улучшаем Perceived Performance

•Увеличивая реальную производительность

113

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

Улучшаем Perceived Performance

•Увеличивая реальную производительность •Замедляя реальную производительность

114

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

Улучшаем Perceived Performance•Увеличивая реальную производительность •Замедляя реальную производительность •Грамотно перераспределяя нагрузку и ресурсы

115

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

116

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

FRPfunctional reactive programming

117

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

this.form.valueChanges .filter((value) => this.form.valid) .switchMap((value) => { return http.post(‘/api’, value) });

118

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

this.form.valueChanges .debounce(500) .filter((value) => this.form.valid) .switchMap((value) => { return http.post(‘/api’, value) });

119

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

this.form.valueChanges .debounce(500) .distinctUntilChanged() .filter((value) => this.form.valid) .switchMap((value) => { return http.post(‘/api’, value) });

120

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

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); }) ))

121

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

122

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

Алексей ОхрименкоTwitter: @Ai_boy

IPONWEB

http://bit.ly/2eMOBjm

123