100% found this document useful (2 votes)
3K views25 pages

Angular 20

Angular v20 introduces significant enhancements, including stabilized APIs, improved debugging tools, and advancements in reactivity with Signals. The release promotes features like zoneless applications and incremental hydration to stable status, while also adding experimental APIs for managing asynchronous state. Additionally, the developer experience has been polished with updates to the style guide, diagnostics, and integration with Chrome DevTools for better performance insights.

Uploaded by

JJ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
100% found this document useful (2 votes)
3K views25 pages

Angular 20

Angular v20 introduces significant enhancements, including stabilized APIs, improved debugging tools, and advancements in reactivity with Signals. The release promotes features like zoneless applications and incremental hydration to stable status, while also adding experimental APIs for managing asynchronous state. Additionally, the developer experience has been polished with updates to the style guide, diagnostics, and integration with Chrome DevTools for better performance insights.

Uploaded by

JJ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 25
Openin app 7 Medium = @ sexe» a Get unlimited access to the best of Medium for less than $1/week. Become amember x Announcing Angular v20 18minread - Draft £ Minko Gechev © listen (1) Share + More ‘The past couple of years have been transformative for Angular, as we've unleashed major advancements like reactivity with Signals and the power of Zoneless applications. We hope these features have helped the Angular community build the next generation of web applications with fast time-to-market and robust performance. MN Angular” And we are just getting started! Angular v20 is our latest release where we have spent countless hours polishing some of our in-progress features for the rock-solid developer experience that you deserve. Some of the highlights: Stabilizing APIs such as effect, linkedSignal, toSignal , incremental hydration, route-level render mode config and promoting zoneless to developer preview Improved debugging with Angular DevTools and partnering with Chrome for custom Angular reporting directly in Chrome DevTools Polishing developer experience with style guide updates, type checking and language service support for host bindings, support for untagged template literal expressions in templates, template hot module replacement by default, and more. Advancements in GenAI development with llms.txt and angular.dev guides and videos for building Generative AI applications Launching a request for comments for an official mascot for Angular Promoting reactivity features to stable We spent the past three years rethinking Angular’s reactivity model to make it more robust and future-proof. In Angular v16 we shipped a developer preview of Angular Signals and since then, they got a wide adoption in and outside of Google. YouTube shared on stage how using Angular Signals with Wiz, they improved input latency in Living Room with 35%. In the meantime, TC39 kicked off an investigation to introduce Signals to the JavaScript language with reference implementation based on Angular Signals. After collecting feedback from RFCs and iterating on the implementation, we promoted signal, computed, input and view queries APIs to stable. Today, we are announcing effect, Linkedsignat and tosignat as stable as well. New, experimental APIs To tackle managing asynchronous state with Angular, in v19 we developed the resource API. Since then, we introduced resource streaming and created a new API called httpresource that allows you to make HTTP requests with a Signal-based reactive API. Both of these APIs are available as part of v20 as experimental. The resource API allows you to initiate an asynchronous action when a signal changes and expose the result of this action as a signal: const userId: Signal = getUserId(); const userResource = resource({ params: () => ({id: userd()}), loader: ({request, abortSignal}): Promise => { // fetch cancels any outstanding HTTP requests when the given ‘AbortSignal” // indicates that the request has been aborted. return fetch(*users/${request.id}’, {signal: abortSignal}) ; s ns —=Z— EP >} The code above will fetch the user with the particular identifier, when the usertd signal changes. Now let’s suppose we're getting data from a WebSocket. For this purpose we can use a streaming resource: @Component ({ template: *{{ dataStream.value() }}° p export class App { // WebSocket initialization logic will Live here... Wove // Initialization of the streaming resource dataStream = resource({ stream: () => { return new Promise>>((resolve) => { const resourceResult = signal<{ value: string] }>({ value: (1, Ds this.socket.onmessage = event => { resourceResult.update(current => ({ value: [...current.value, event.data] Ys resolve(resourceResult) 5 Ys ty Ds In this minimal example, we declare a new streaming resource, which returns a promise of a signal. The signal has a value type ResourceStreantten , which means that the signal can hold the value { value: string(] } or {error: .. } incase we want to return an error. We emit the values we receive over the WebSocket via the resourceResult signal. Building on top of this pattern, we also shipped the experimental httpresource : @Component ({ template: “{{ userResource.value() | json }}° » class UserProfile { userId = signal(1); userResource = httpResourcecUser>(() => “https: //example.com/v1/users/${this.userId()}° Ds + The snippet above will send an HTTP GET request to the URL we specified every time when the userId changes. httpResource returns HttpResourcekef which has a value property of type signal that we can directly access in the template. The userResource has other values, such as istoading, headers , and others, as well. Under the hood, httpresource uses HttpClient so you can specify interceptors in the HttpClient provider: bootstrapApplication(AppComponent, {providers: [ provideHttpClient( withInterceptors([loggingInterceptor, cachingInterceptor]), I); Promoting Zoneless to developer preview Over the past six months, we made a lot of progress in zoneless, specifically around server-side rendering and error handling. Many developers use Zone.js for capturing errors in their apps even without realizing it. Zone.js also lets the framework know when we're ready to flush the server-side rendered application to the client. In the world of zoneless, we had to find robust solutions for these problems. In v20 we now have a default handler for unhandtedrejection and uncaughtexception in Node,js during SSR to prevent the node server from crashing in case of errors. On the client, you can include provideBrowserGlobalérrorListeners in your providers. You can start using zoneless today by updating your list of providers: bootstrapAppLication(AppComponent, {providers: [ provideZonelesschangeDetection() , provideBrowserGlobalErrorListeners() ns In addition, make sure you remove the zone.js polyfill from your angular.json « Learn more about the benefits of zoneless and how to transition your project in our documentation. If you’re creating a new Angular project, you can get it to be zoneless from the start using the CLI: Solidifying Angular on the server In v20 we also focused on polishing our flagship server-side rendering features — incremental hydration and route-level rendering mode configuration. Today, we're happy to promote both of them to stable! As a reminder, incremental hydration makes your apps faster by downloading and hydrating a portion of the page on a particular trigger. This way, your users don't have to download all the JavaScript associated with a particular page, instead they can gradually download only the parts that they need. To start using incremental hydration today, configure hydration by specifying withIncrementalHydration : ‘import { provideClientHydration, withIncrementalHydration } from '@angular/plat provideClientHydration(withincrementalHydration()); ———— > In the templates of your components now you can use deferrable views: @defer (hydrate on viewport) { + That way, Angular will download the shopping cart component together with its transitive dependencies and hydrate this part of the UI only when it enters the viewport. Additionally, you can now use route-level rendering mode configuration as a stable API! If different routes in your app have different rendering requirements, you can configure that in a server-route configuration: export const routeConfig: ServerRoute = [ { path: '/login', mode: RenderMode.Server }, { path: '/dashboard', mode: RenderMode.Client }, { path: '/product/:id', mode: RenderMode.Prerender, async getPrerenderParams() { const dataService = inject (ProductService) ; const ids = await dataService.getIds(); // ["1", "2", "3"] J] “id? is used in place of *:id’ in the route path. return ids.map(id => ({ id }))5 In the snippet above we configure to render the login page on the server, the dashboard on the client, and prerender the product pages. Notice that the product page requires an id parameter. To resolve the identifiers for each product, we can use the asynchronous function get?rerenderParams . It returns an object in which its keys map to router parameters. In the case of the /product/:id page we return an object with an ia property. You can host your server-side rendered apps with most cloud providers. We partnered closely with Firebase App Hosting on a seamless deployment story that supports hybrid rendering (SSR, SSG, and CSR) and provides you the security and scalability of Google Cloud. Polishing developer experience We spent a lot of time while developing v20 on engineering excellence — polishing existing APIs to improve your developer experience. We did this across the board — framework, router, forms, http, etc. Let me share more about the work we did here! Performance insights in Chrome DevTools To further enhance the developer experience and provide deeper insights into application performance, we've collaborated with the Chrome DevTools team to integrate Angular-specific profiling data directly into the Performance panel. Previously, developers often had to switch between framework-specific profilers and the browser’s DevTools, making it challenging to correlate information and pinpoint bottlenecks, especially with minified production code. This new integration aims to solve that by displaying Angular runtime data, such as component rendering, change detection cycles, and event listener execution, within the same timeline as other browser performance metrics. This direct integration, available starting in Angular v20, leverages the Performance panel extensibility API, specifically using the console.timestamp API for its low overhead, ensuring that profiling doesn't negatively impact application performance. Developers can now gain enhanced visibility into Angular’s internal workings, with color-coded entries to distinguish between developer-authored TypeScript code and Angular compiler-generated code. To enable this feature, simply run the global utility ng.enabteProfiting() in your application or the DevTools console. This advancement provides a more intuitive and comprehensive performance analysis experience, empowering developers to build even more performant Angular applications. eee neds -teioniee) GR LB Console Clements sopleaon Sources _Perlormance Angusr Network A Memory Ustnouse m2 Oi BOC 2s @ rarcan enhets Coaenery dC) Dara panies BO i Lerenm yao 26m ‘B CatapeeCampanert Template buton ek 50 Jstene ona Whats row Notwarkcandions teint Search Alaieitance Prlacolmontor —Pelomance mentor BO wm © Trw Oninublewe + 2hevee 2B On the screenshot above, you can see this feature in action. Notice how at the bottom of the performance timeline there's a track dedicated to Angular. With the color-coded bars, you can preview component instantiation, running change detection, etc. Both Angular DevTools and the Angular track in the Chrome performance timeline use the same hooks with the difference that Chrome’s performance timeline can put your app’s lifecycle into the context of other JavaScript calls outside the framework. In addition, the Angular track in Chrome’s performance timeline shows some data that’s currently not present in Angular DevTools, such as component and provider instantiation. Framework additions and improvements To dynamically create an Angular component you can use the createComponent function. In v20 we introduce new features that let you apply directives and specify bindings to dynamically created components: import {createComponent, signal, inputBinding, outputBinding} from '@angular/cc const canClose = signal (false) ; const title = signal('My dialog title’); // Create MyDialog createComponent (MyDialog, { bindings: [ // Bind a signal to the ‘canClose’ input. ‘inputBinding('canClose', canClose) , // Listen for the ‘onClose’ event specifically on the dialog. outputBinding('onClose', result => console. log(result)), // Creates two way binding with the title property twoWayBinding(‘title', title), 1, directives: [ // Apply the ‘FocusTrap’ directive to ‘MyDialog’ without any bindings. FocusTrap, // Apply the “HasColor’ directive to ‘MyDialog’ and bind the ‘red’ value tc // The callback to “inputBinding’ is invoked on each change detection. t type: HasColor, bindings: [inputBinding(‘color', () => 'red")] + 1 Ds SD > Above we create a dialog component and specify: © canctose input binding, passing the signal canctose as a value * Set the output onctose toa callback that logs the emitted result * Two way binding between the title property and the title signal Additionally, we add the rocustrap and Hascotor directives to the component. Notice that we can also specify input bindings for the Hascotor directive that we apply to MyDialog . Extended template expression syntax We've been bridging the gap between Angular template expressions and full JavaScript syntax to enable higher expressiveness and better developer experience. Today, we're introducing support for the exponential operator +» and in operator: {Ln 23} {{ name in person }} In v20 we also enable you to use untagged template literals directly in expressions:
Extended diagnostics To guard against common errors, we introduced static checks that detect invalid nullish coalescing, detection of missing imports for structural directives, and a warning when you don't invoke the track function you've passed to efor : @Component ({ template: * Gfor (user of users; track trackFn) {

You might also like