Skip to main content

One post tagged with "template"

View All Tags

· 7 min read
Michael Hladky
Edouard Bozon
Julian Jandl
Kirill Karnaukhov
Lars Gyrup Brink Nielsen

We are pleased to announce the stable release of RxAngular CDK and RxAngular Template 1.0. With this release, we enter semantic versioning which means no breaking changes in minor or patch version releases. This includes version requirements for our peer dependencies, Angular and RxJS.

Thank you to all contributors and users who have helped us to get here. We are excited to see what the future holds for RxAngular.

TOC

Packages introduction

@rx-angular/template

The @rx-angular/template library simplifies building Angular applications of any scale. It improves the DX by reducing boilerplate code and provides fast and reliable change detection. It's implementation is zone agnostic by default and optimizes internally regardless of the environment. By leveraging the @rx-angular/cdk/render-strategies package, it enables the concurrent mode for #angular

Push pipe: A Better Alternative to Async Pipe

The push pipe works like the async pipe but offers prioritized scheduling and local change detection. This means optimized cd cycles resulting in better performance. Unlike the async pipe, the push pipe can work in environments without zone.js.

RxLet directive: Advanced Template Control

rxLet directive

The rxLet directive is a tool that replaces the standard async pipe. In addition to prioritized scheduling it also offers a scoped rendering. This directive allows you to fine-tune change detection in specific parts of your components template, without affecting the rest of the component or application. The scoped rendering gives you more control over how Angular updates your user interface.

Reactive context and context triggers: Dynamic Templates

context triggers

With the rxLet directive, you can bind observables, promises, and other reactive data sources to display different templates based on their state. This includes feedback for suspense, next, error, and complete. You can also provide an observable as a trigger to switch between template types.

RxFor directive: Efficient Lists

rxFor directive

The rxFor directive is a more performant and efficient alternative to the ngFor directive. Unlike ngFor, it allows for non-blocking rendering of large sets of data by treating each child template as a separate renderable unit and executing change detection as separate tasks. This results in a smoother user experience, even when dealing with large or complex lists. You can provide input values as observables, promises, or static values. The rendering behavior can also be customized through the RenderStrategies API.

Check this tweet by Chau Tran to see the ultimate difference between ngFor and rxFor performance.

RxIf directive: Switch Templates Easily

The rxIf directive is an alternative to the ngIf directive. It makes switching templates based on an observable condition easier. Instead of using ngIf with the async pipe, you can bind observables directly to the rxIf directive. This eliminates the need for interactions with NgZone or triggering global change detection, making the process of switching templates more efficient.

@rx-angular/cdk

@rx-angular/cdk offers tools for Angular developers to create efficient directives, components and services. It includes features like zone configuration, zone-less implementation, coercion, coalescing, render-strategies, and more, to improve the performance of Angular applications.

Concurrent strategies: Unblock Main Thread

concurrent strategies

The browser has one main UI thread that performs tasks one after another. Long tasks, over 50ms, affect users experience and it's important to optimize and prioritize code to meet the 50ms frame budget.

@rx-angular/cdk provides concurrent scheduling strategies with a frame budget awareness, task prioritization and execution deadline.

  • Notion of frame budget. The strategies are designed to be aware of the frame budget and schedules work accordingly.
  • Priority. Each strategy is assigned a priority, determining the order in which tasks are executed.
  • Execution deadline. Each strategy has its own execution deadline. If the deadline is exceeded, any remaining work will be executed in a single browser task.

userBlocking strategy

The image shows the execution deadline concept. 6 userBlocking tasks are scheduled. The first 2 tasks meet the deadline and are executed in separate tasks, but the third task exceeds the deadline of 250ms and the scheduler executes all remaining tasks with a deadline <= 250ms in one task.

Native strategies: Improve Default Change Detection

Global vs Local rendering

The library also offers non-chunked rendering strategies, which improve the default Angular rendering approach. By default, Angular evaluates and potentially re-renders the entire component tree, starting from the trigger point and working up to the root of the app. However, our rendering strategies use "detectChanges" to evaluate and update only changed components, making the rendering process more efficient and faster.

Strategy provider: Schedule Any Work

The main way to use RenderStrategies is through template directives and pipes, but the library also provides the RxStrategyProvider service for component-level interaction. This service offers the schedule and scheduleWith methods for scheduling any type of work, with schedule returning an observable and scheduleWith returning a MonoTypeOperatorFunction for use in an rxjs pipe.

The scheduleCD method is an imperative option for scheduling change detection cycles.

Try the RxStrategyProvider and see rendering strategies in action in this stackblitz demo.

Zone configuration and Zone-less utils: Reliable Zone.js tuning

Our CDK provides zone-configuration utils for partially disabling zone.js, reducing the risk of unexpected bugs. These utils provide autocompletion, event groups, and assertions to ensure proper usage. The zone-less utils allow for selective disabling of zone patching for specific browser APIs, including requestAnimationFrame, cancelAnimationFrame, setInterval, clearInterval, setTimeout, clearTimeout. The utility function getZoneUnpatchedApi can be used to get an unpatched version of any browser API.

Coalescing: Optimize Frequent Events

Coalescing sub-package provides set of utilities that implement a technique of merging multiple emissions, streams, or calls into one during a given time frame to improve the performance. This helps to minimize the number of updates made to the user interface, improving the overall efficiency and speed of the application. This technique is one of the key building blocks for optimizing change detection cycles in Angular, and is utilized to ensure that the application is functioning smoothly and effectively.

Coercing: Seamless Type Conversion

Our coercion package provides a set of utilities to perform type coercion (data type conversion) in a seamless and efficient manner. These utilities include factories, such as 'coerceObservable' and 'coerceDistinctObservable', and operators, such as 'coerceObservableWith' and 'coerceDistinctWith'. These tools help to ensure that data is in the desired format before it is used in the application, improving overall functionality and preventing unexpected errors.

Transformations Tree Shakable Entity Management

The transformation helpers provided by the @rx-angular/cdk/transformations are a complete set of utilities to manage entities. They are immutable by default and include transformation functions to handle insertions, updates, dictionary <-> array conversions & more to help you build store like state management systems.

Roadmap

We also want to give a brief overview about the future steps we want to take with the RxAngular libraries.

Right now, the RxAngular monorepo and all of its libraries are based on angular v12. This is because of backwards compatibility to pre-ivy projects. While we like the idea of being backwards compatible, we have made the decision to move forward and upgrade the whole project to the latest Angular version available. We want to make sure to build modern solutions based on the new APIs introduced with the latest changes to the Angular framework itself.

Some things we are investigating right now:

  • new provider functions (withFeature)
  • easier creation of state (inject)
  • signals integration into @rx-angular/state
  • signals integration into @rx-angular/template
  • concurrent mode with signals

That being said, we will release the next major versions very soon and we have decided to sync the @rx-angular/* versions with the Angular versions, giving us the ability to provide two breaking changes a year.

RxAngularAngular version
^1.0.0>=12.0.0
^2.0.0>=13.0.0
^14.0.0^14.0.0
^15.0.0^15.0.0
^16.0.0^16.0.0