Reactivity With Signals

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

Reactivity with Signals

Is this the future of Angular development?

Gergely Szabó
● Live in Veszprém
● Love outdoor activities like hiking,
geocaching, cycling
● In my free time developing home
projects

● Graduated as a Computer Science


Engineer
Gergely Szabó ● Main orientation is frontend
Software Engineer - Google
● Working with Angular since 2018
AutoML Vision Video Language Speech BigQuery

No code / low
Translation Tables Forecast Tabnet Workflows BigQuery ML
code workflow

Generative AI Studio | Generative AI APIs | Model Garden

Vertex AI Data Science


Workbench

tool kit
A Unified ML Platform Integration with Cloud
Storage
BigQuery Spark Spanner BI
Data Services
for Solving All Business Problems
Experiment Train Deploy

Datasets Training Prediction

● Unified development and Custom


deployment platform for machine workflow Vertex SDK NAS Matching Engine

learning at scale
Streaming
Experiments Vizier
Ingestion
● Increase productivity of data
scientists and ML engineers
Model Explainable ML Feature Model Model
● Improve time to value Monitoring AI Metadata Store Registry Evaluation
MLOps

Pipelines
Agenda

1 Change detection in Angular

2 Introduction of Signals

3 Future of Signals

4 Q&A
Change detection in
Angular
Component structure
● Template
○ interpolations
○ components with bindings
○ pipes
○ event handlers
○ …
● Component
○ Inputs
○ Outputs
○ properties
○ functions
○ …
Component after build
Component change detection cycle

Every component extends ViewRef that implements


detectChanges
ChangeDetectorRef

refreshView Handles all lifecycle hooks except onDestroy

executeTemplate Runs templateFn in creation and update mode

detectChanges
for child components
Runs detectChanges for every child component
Zone.js

● A zone is an execution context that persists across async tasks


● First introduced in 2013 at the AngularJS conf
● Originally created by Victor Savkin, a software engineer at Google. He
was inspired by the concept of zones from the Erlang programming
language.
● In 2016, Zone.js was released as a standalone JavaScript framework
● Still actively developed and maintained by the Angular team at Google
● Mainly used for handle trigger change detection
🐒 patching
Standard API
● Macro tasks
○ setInterval/setTimeout
○ requestAnimationFrame/cancelAnimationFrame
○ …

● Micro tasks
○ Promise
○ HttpRequest
○ …

● Event tasks
○ All 'on' properties, such as onclick, onreadystatechange …
○ FileReader, Worker, IDBDatabase, Performance …
setTimeout clearTimeout setImmediate clearImmediate setInterval clearInterval requestAnimationFrame
cancelAnimationFrame webkitRequestAnimationFrame webkitCancelAnimationFrame alert prompt confirm
Promise EventTarget HTMLElement on properties XMLHttpRequest.send/abort XMLHttpRequest on properties
mozRequestAnimationFrame IDBIndex on properties IDBRequest on properties IDBOpenDBRequest on
properties IDBDatabaseRequest on properties IDBTransaction on properties IDBCursor on properties

150+
WebSocket on properties MutationObserver WebkitMutationObserver FileReader registerElement
ApplicationCache MediaController SVGElementInstance TextTrackList WorkerGlobalScope IDBRequest
IDBCursor EventSource MessagePort SharedWorker WebKitNamedFlow XMLHttpRequest IDBOpenDBRequest
DBIndex FileReader Node TextTrack Window XMLHttpRequestEventTarget IDBDatabase WebSocket
InputMethodContext Performance TextTrackCue Worker XMLHttpRequestUpload IDBTransaction copy blur
change drag dragover emptied keydown loadeddata mousedown mouseout play reset select suspend
mozfullscreenchange error cut focus click dragend dragstart mozCancelAnimationFrame ended keypress
loadedmetadata mouseenter mouseover playing scroll show timeupdate mozfullscreenerror
webglcontextrestored paste canplay contextmenu dragenter drop input keyup loadstart mouseleave mouseup
progress seeked stalled volumechange mozpointerlockchange webglcontextlost abort canplaythrough dblclick
dragleave durationchange invalid load message mousemove pause ratechange seeking submit waiting
Non Standard API

● MediaQuery APIs
● Notification APIs

15+
● Bluebird APIs
● Canvas API
● Electron API
● rxjs API
● Shady DOM APIs
Zone.js process

bootstrapModule
detectChanges

new
refreshView
NgZone()

onMicrotaskEmpty
executeTemplate

detectChanges
ApplicationRef.tick()
for child components
Zone.js process

bootstrapModule
detectChanges

new
refreshView
NgZone()

onMicrotaskEmpty
executeTemplate

detectChanges
ApplicationRef.tick()
for child components
Zone.js process

bootstrapModule
detectChanges

new
refreshView
NgZone()

onMicrotaskEmpty
executeTemplate

detectChanges
ApplicationRef.tick()
for child components
Component change detection cycle

Every component extends ViewRef that implements


detectChanges
ChangeDetectorRef

refreshView Handles all lifecycle hooks except onDestroy

executeTemplate Runs templateFn in creation and update mode

detectChanges
for child components
Runs detectChanges for every child component
ChangeDetectionStrategy.Default
ChangeDetectionStrategy.Default

Pros
● Simpler code
● More predictable behavior for smaller applications
● Better support for third-party libraries

Cons
● Reduced performance for large applications
● Reduced predictability for complex applications
● Reduced support for reactive programming
ChangeDetectionStrategy.OnPush

detectChanges

refreshView

After the root component executeTemplate it runs


executeTemplate detectChanges only in child which is dirty

isDirty?

detectChanges
for child components
ViewRef.markForCheck()
ViewRef.markForCheck()

● Every class function patched with markForCheck function


● @Input changes
● Event binding, output binding, or @HostListener
● The component was explicitly marked for check via
ChangeDetectorRef.markForCheck()
● async pipe markForCheck the component every time when new value
emitted
● Schedule change detection after the current execution context finished
ChangeDetectionStrategy.OnPush
Zoneless change detection
Change detection edge cases

● Do not use function in template. Angular can’t track the function result
and it re renders the template in every change detection cycle.
● Having a parent component with change detection strategy OnPush and
a child component with strategy Default could result in an outdated
view, as change detection potentially could not run on the child
component.
Introduction of Signals
Basics

● Available for developer preview from Angular 16


● ~2 KB
● Granularly tracks how and where your state is used throughout an
application, allowing the framework to optimize rendering updates.
● May change before they are stable
● Wrapper around a value that can notify interested consumers when that
value changes
● Can contain any value, from simple primitives to complex data
structures
Create and read signal

● Initial value required


● Signals are getter functions - calling them reads their value.
Change signal value

● set: override the value


● update: the parameter is a function, gives immutable copy
● mutate: the parameter is a function, gives mutable reference
Change signal value

● set: override the value


● update: the parameter is a function, gives immutable copy
● mutate: the parameter is a function, gives mutable reference
Computed signals
● Define one using computed and specifying a derivation function
● The doubleCount signal depends on count
● Derivation function does not run to calculate its value until the first time
doubleCount is read.
● Once calculated, this value is cached
● Computed signals are not writable signals
Computed signals

● Computed signal dependencies are dynamic


Effect
● An effect is an operation that runs whenever one or more signal values change
● Similar to computed signals, effects keep track of their dependencies dynamically,
and only track signals which were read in the most recent execution
● Effects always execute asynchronously, during the change detection process
● Avoid using effects for propagation of state changes.
Use cases for effects

● Logging data being displayed and when it changes, either for analytics or
as a debugging tool
● Keeping data in sync with window.localStorage
● Adding custom DOM behavior that can't be expressed with template
syntax
● Performing custom rendering to a <canvas>, charting library, or other
third party UI library
Injection context
● effect() function requires an
injection context
● The easiest way to provide this is
to call effect within a component,
directive, or service constructor
● Alternatively, the effect can be
assigned to a field
● Outside of the constructor, you
can pass an Injector to effect via
its options
Destroying effects
● Automatically destroyed
when its enclosing
context is destroyed
● Effects return an
EffectRef that can be
used to destroy them
manually, via the
.destroy() operation
● This can also be
combined with the
manualCleanup
Signal equality functions
● Optionally provide an equality function
● Equality functions can be provided to both writable and computed
signals
● For writable signals, .mutate() does not check for equality
Reading without tracking dependencies
● computed or effect without creating a dependency
● untracked is also useful when an effect needs to invoke some external
code
Effect cleanup functions
● effect can optionally accept an onCleanup function as its first parameter
● Effects might start long-running operations, which should be cancelled
if the effect is destroyed
BehaviorSubject vs effect
Conversation functions

● toObservable function
creates a ReplaySubject and
wraps the provided signal in
an effect. When the signal
value changes, the effect will
emit the new value
● toSignal function subscribes
to the observable
immediately
● ensure that it is being called in
an injection context
Near real-word example
Signals could replace rxjs?

● Not subscribes to every change


● Lack of third party library support
● Not chainable like pipe
● No operators available (map, tap, throttleTime, debounceTime)
● Solves different problem
How Signals works together with Zone.js?

Default

● No change, trigger changeDetection for every component in signal


changes

OnPush

● Similar as Observables, mark component dirty when signal changed but


without async pipe
● Tracks the signal as a dependency of that component
Future of Signals
Timeline
Signal-based components

● RFC: https://github.com/angular/angular/discussions/49682
● Expected to available in Angular 18-19
● Inputs and Outputs also signals
● Zoneless application
● ngAfterContentInit, ngAfterViewChecked and ngAfterContentChecked
lifecycle hooks being removed
● Granularity of change detection
Q&A
Reference
● "The bright future of Angular Signals"
https://www.youtube.com/watch?v=m_h_WnoO8Ms
● Change Detection in Angular - Pt.1 View Checking
https://youtu.be/hZOauXaO8Z8
● Change Detection in Angular Pt.2 - The Role of ZoneJS (2023)
https://www.youtube.com/watch?v=Ys7xdebd66Y
● Change Detection in Angular Pt.3 - OnPush Change Detection Strategy
https://www.youtube.com/watch?v=WAu7omIoerM
● Rethinking reactivity with Angular Signals
https://www.youtube.com/watch?v=EIF0g9LDHcQ

You might also like