twitter.com/mgechev
Observer Pattern
‣ Push based
‣ State triggers an event on change
‣ View handles the event and updates
Slide 14
Slide 14 text
// state.ts
class State extends EventEmitter {...}
const state = new State({ todos: [] });
state.todos.push('Buy milk');
state.emit(Change)
// view.ts
class View {
// more code
update(state) {
// visualize todos
}
}
const view = new View();
state.on(Change, _ => view.update(state));
Slide 15
Slide 15 text
// state.ts
class State extends EventEmitter {...}
const state = new State({ todos: [] });
state.todos.push('Buy milk');
state.emit(Change)
// view.ts
class View {
// more code
update(state) {
// visualize todos
}
}
const view = new View();
state.on(Change, _ => view.update(state));
Slide 16
Slide 16 text
twitter.com/mgechev
Virtual Dom
‣ State renders in a “virtual view”
‣ Diff between the last two
versions of the “virtual view”
‣ Diff applied to the view
Slide 17
Slide 17 text
[]
State
TODOS
APP
INPUT BUTTON
Slide 18
Slide 18 text
TODOS
APP
INPUT BUTTON
State
['Buy milk']
Slide 19
Slide 19 text
State
['Buy milk']
TODOS
APP
INPUT BUTTON
TODOS
APP
INPUT BUTTON
TODO
Slide 20
Slide 20 text
State
['Buy milk']
TODOS
APP
INPUT BUTTON
TODOS
APP
INPUT BUTTON
TODO
Slide 21
Slide 21 text
State
['Buy milk']
TODOS
APP
INPUT BUTTON
TODO
Slide 22
Slide 22 text
State
['Buy milk']
TODOS
APP
INPUT BUTTON
TODO
Slide 23
Slide 23 text
twitter.com/mgechev
Dirty Checking
‣ Pull based
‣ Framework checks for state updates
‣ Framework update the view
Slide 24
Slide 24 text
twitter.com/mgechev
Dirty Checking
‣ Pull based
‣ Framework checks for state updates
‣ Framework update the view
Slide 25
Slide 25 text
twitter.com/mgechev
When?
Slide 26
Slide 26 text
twitter.com/mgechev
Dirty Checking
‣ After each event callback
‣ After each network message
‣ After each timeout callback
‣ …
Slide 27
Slide 27 text
sample.ts
fetch(url)
.then(r => r.json())
.then(data => {
// mutate the state
detectChanges();
});
timeout(() => {
// mutate the state
detectChanges();
}, 1000);
btn.addEventListener('click', () => {
// mutate the state
detectChanges();
});
const detectChanges = _ => {
if (state !== prevState) {
updateView(state);
}
};
Slide 28
Slide 28 text
sample.ts
fetch(url)
.then(r => r.json())
.then(data => {
// mutate the state
detectChanges();
});
timeout(() => {
// mutate the state
detectChanges();
}, 1000);
btn.addEventListener('click', () => {
// mutate the state
detectChanges();
});
const detectChanges = _ => {
if (state !== prevState) {
updateView(state);
}
};
Slide 29
Slide 29 text
sample.ts
fetch(url)
.then(r => r.json())
.then(data => {
// mutate the state
detectChanges();
});
timeout(() => {
// mutate the state
detectChanges();
}, 1000);
btn.addEventListener('click', () => {
// mutate the state
detectChanges();
});
const detectChanges = _ => {
if (state !== prevState) {
updateView(state);
}
};
Slide 30
Slide 30 text
sample.ts
fetch(url)
.then(r => r.json())
.then(data => {
// mutate the state
detectChanges();
});
timeout(() => {
// mutate the state
detectChanges();
}, 1000);
btn.addEventListener('click', () => {
// mutate the state
detectChanges();
});
const detectChanges = _ => {
if (state !== prevState) {
updateView(state);
}
};
Slide 31
Slide 31 text
sample.ts
fetch(url)
.then(r => r.json())
.then(data => {
// mutate the state
detectChanges();
});
timeout(() => {
// mutate the state
detectChanges();
}, 1000);
btn.addEventListener('click', () => {
// mutate the state
detectChanges();
});
const detectChanges = _ => {
if (state !== prevState) {
updateView(state);
}
};
Slide 32
Slide 32 text
twitter.com/mgechev
Zone.js intercepts all tasks
and micro tasks
twitter.com/mgechev
view.checkNoChanges slows us
down in production, at least twice!
Slide 52
Slide 52 text
twitter.com/mgechev
Always invoke enableProdMode
in our production applications
Default behavior for the production builds of Angular CLI, angular seed
Practice #2
Slide 53
Slide 53 text
twitter.com/mgechev
How Angular Updates The View
‣ Checks for changes in the state
‣ Applies only required updates
Slide 54
Slide 54 text
twitter.com/mgechev
Angular generates code for performing
change detection and updating the view
Slide 55
Slide 55 text
twitter.com/mgechev
Generation Could Be
‣ Runtime, a.k.a. Just-in-Time
‣ Build time, a.k.a. Ahead-of-Time
Slide 56
Slide 56 text
No content
Slide 57
Slide 57 text
twitter.com/mgechev
Performing the compilation step runtime
(JiT) slows down the initial rendering
Slide 58
Slide 58 text
twitter.com/mgechev
Use Ahead-of-Time
compilation in production
Default behavior for the production builds of Angular CLI, angular seed
Practice #3
Slide 59
Slide 59 text
twitter.com/mgechev
Use Ahead-of-Time
compilation in production
Default behavior for the production builds of Angular CLI, angular seed
Practice #3
everywhere
Slide 60
Slide 60 text
twitter.com/mgechev
The best way to speed-up the change
detection is to not perform it at all!
Slide 61
Slide 61 text
twitter.com/mgechev
ChangeDetectorRef
Slide 62
Slide 62 text
twitter.com/mgechev
ChangeDetectorRef
‣ Detach the change detector
‣ Check for changes manually
‣ Re-attach the change detector
Allows us to:
twitter.com/mgechev
Externalize the state and use OnPush for
skipping CD for component subtrees
Practice #5
Slide 91
Slide 91 text
twitter.com/mgechev
Pipes
Slide 92
Slide 92 text
twitter.com/mgechev
Memoization is a technique used to speed up programs
by storing the results of function calls and returning the
cached result when the same inputs occur again.
Slide 93
Slide 93 text
twitter.com/mgechev
Pure Functions
‣ Same result when invoked with same arguments
‣ Do not have side-effects
Can be optimized with memoization because: