Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reactivity with Signals - by Gergely Szabo @Google

Marcell Kiss
September 27, 2023

Reactivity with Signals - by Gergely Szabo @Google

Marcell Kiss

September 27, 2023
Tweet

More Decks by Marcell Kiss

Other Decks in Technology

Transcript

  1. Gergely Szabó Software Engineer - Google • Live in Veszprém

    • Love outdoor activities like hiking, geocaching, cycling • In my free time developing home projects • Graduated as a Computer Science Engineer • Main orientation is frontend • Working with Angular since 2018
  2. Vertex AI • Unified development and deployment platform for machine

    learning at scale • Increase productivity of data scientists and ML engineers • Improve time to value Integration with Data Services Experiment Train Deploy Datasets Experiments Vertex SDK Training Vizier NAS Prediction Pipelines Workbench Custom workflow No code / low code workflow Matching Engine MLOps Data Science tool kit BigQuery Spark Cloud Storage Vision Video Language Speech Forecast BigQuery ML Translation Tables Spanner Model Monitoring Explainable AI Feature Store ML Metadata Model Registry Model Evaluation Workflows Tabnet Streaming Ingestion BI AutoML BigQuery A Unified ML Platform for Solving All Business Problems Generative AI Studio | Generative AI APIs | Model Garden
  3. Component structure • Template ◦ interpolations ◦ components with bindings

    ◦ pipes ◦ event handlers ◦ … • Component ◦ Inputs ◦ Outputs ◦ properties ◦ functions ◦ …
  4. Component change detection cycle Every component extends ViewRef that implements

    ChangeDetectorRef detectChanges refreshView executeTemplate detectChanges for child components Handles all lifecycle hooks except onDestroy Runs templateFn in creation and update mode Runs detectChanges for every child component
  5. 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
  6. 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 …
  7. 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 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 150+
  8. Non Standard API • MediaQuery APIs • Notification APIs •

    Bluebird APIs • Canvas API • Electron API • rxjs API • Shady DOM APIs 15+
  9. Component change detection cycle Every component extends ViewRef that implements

    ChangeDetectorRef detectChanges refreshView executeTemplate detectChanges for child components Handles all lifecycle hooks except onDestroy Runs templateFn in creation and update mode Runs detectChanges for every child component
  10. 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
  11. ChangeDetectionStrategy.OnPush detectChanges refreshView executeTemplate detectChanges for child components isDirty? After

    the root component executeTemplate it runs detectChanges only in child which is dirty
  12. 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
  13. 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.
  14. 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
  15. Create and read signal • Initial value required • Signals

    are getter functions - calling them reads their value.
  16. 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
  17. 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
  18. 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
  19. 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.
  20. 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
  21. 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
  22. 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
  23. 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
  24. Reading without tracking dependencies • computed or effect without creating

    a dependency • untracked is also useful when an effect needs to invoke some external code
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. Q&A

  31. • "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 Reference