Angular v17 is officially released!

Original text: Introducing Angular v17

Last month marked the 13th anniversary of Angular’s ​​red shield. AngularJS (note that AngularJS is not Angular, which is the 1.x version) is the starting point of a new wave of JavaScript frameworks designed to support the growing demand for rich web experiences. Today, we're taking you into the future with v17, with a new look and a set of forward-looking features, laying a new foundation for performance and development experience.

In v17 we are happy to introduce:

  • Deferrable views Deferrable views take performance and development experience to the next level, officially stable from development preview
  • In public benchmarks , runtime improved by 90% with loops built into control flow
  • Builds are 87% faster for hybrid rendering and 67% faster for client-side rendering
  • A new look represents Angular’s ​​future-oriented features
  • Brand new interactive learning tutorials, from simple to in-depth, including online playground
  • And many other features and improvements!

Future-proof identity

The Angular renaissance has been in full swing for the past few releases. We've been building momentum with improvements like signal-based reactivity, hydration, independent components, combined instructions, and many other features. Although Angular has grown rapidly, its brand hasn't kept up - it's pretty much the same since the early days of AngularJS.


Today, the framework you love and tested by millions of developers gets a new look that reflects its future-proof development experience and performance!

Documentation for the future

Along with the new brand, we've also developed a new home for Angular documentation — angular.dev. For the new documentation site, we've adopted a new structure, new guidance, improved content, and built an interactive learning journey platform that allows you to learn Angular and the Angular CLI at your own pace, right in your browser.


The new interactive learning experience is powered by WebContainers , allowing you to use the power of Angular CLI in any modern web browser!  

 

Today, we are launching a beta preview of angular.dev and plan to make it the default website for Angular in v18. You can learn more about Angular's new look and angular.dev at Angular.dev It's Coming (original text Announcing angular.dev ). 


Now let me dive into the features of v17, we can’t wait to show you!

Built-in control flow

To improve the development experience, we've released a new block template syntax that gives you powerful functionality through a simple, declarative API. Under the hood, the Angular compiler converts syntax into efficient JavaScript instructions that can perform control flow, lazy loading, and more.

We use the new block syntax to implement an optimized built-in control flow. After conducting user research, we found that many developers were experiencing some difficulties using , and . Having been using Angular since 2016 and being part of the Angular team for the past 5 years, I personally still need the syntax for finding and . After gathering feedback from the community, partners, and conducting user experience research, we developed a new built-in control flow for Angular! *ngIf  *ngSwitch  *ngFor  *ngFor  trackBy 

Built-in control flow can:

  • More comfortable syntax, closer to JavaScript and therefore more intuitive and requiring less documentation lookups
  • Better type checking thanks to optimized type narrowing
  • This is a concept that exists primarily at build time and can reduce the runtime footprint (make it "disappear"), thereby reducing your bundle size by up to 30 KB and further improving your Core Web Vital score
  • It will be automatically available in your template without additional import. In the past, structural directives required importing NgIf, NgFor, etc. in the common module.
  • Significant performance improvements will be introduced later

Conditional statements

Let's take a look at *ngIfthe comparison with:

<div *ngIf="loggedIn; else anonymousUser">
  The user is logged in
</div>
<ng-template #anonymousUser>
  The user is not logged in
</ng-template>

Using the built-in if statement, this condition would look like this:

@if (loggedIn) {
  The user is logged in
} @else {
  The user is not logged in
}

Being able to fill in the template content directly is a major simplification compared to the older alternative's else clause . The current flow of control also makes it possible that was not possible with structural instructions in the past. *ngIf @else @else if 

*ngSwitch The improvement effect is more obvious:

<div [ngSwitch]="accessLevel">
  <admin-dashboard *ngSwitchCase="admin"/>
  <moderator-dashboard *ngSwitchCase="moderator"/>
  <user-dashboard *ngSwitchDefault/>
</div>

With built-in control flow, it becomes:

@switch (accessLevel) {
  @case ('admin') { <admin-dashboard/> }
  @case ('moderator') { <moderator-dashboard/> }
  @default { <user-dashboard/> }
}

The new control flow allows for better type narrowing in individual branches, which is not possible with structural instructions. @switch  *ngSwitch 

Built-in for loop

One of my favorite updates is the built-in for loop we introduced, which, in addition to improving the development experience, pushes Angular's rendering speed to another level!

Its basic syntax is:

@for (user of users; track user.id) {
  {{ user.name }}
} @empty {
  Empty list of users
}

We often see performance issues in applications due to *ngFormissing trackByfunctionality. Some of the differences are that track is mandatory to ensure quick comparison of performance. Additionally, it's easier to use since it's just an expression rather than a method in the component class. The built-in loop also has a shortcut for zero-item collection via optional blocks. @for@for @empty 

@for Statements use a new comparison algorithm and have a more optimized implementation compared to , which results in a 90% improvement in running time on the Community Framework benchmark! *ngFor 

Give it a try!

Built-in control flow is now available in v17 developer preview!

One of the design goals of the built-in control flow is to enable fully automated migrations. To try it out in an existing project, use the following Schematics one-click migration:

ng generate @angular/core:control-flow

What's next?

You can already use built-in control flow with the latest language services, and we work closely with JetBrains to provide better support in their products. We also contacted Sosuke Suzuki at Prettier to ensure that the Angular templates would be formatted correctly.  

*ngIfThere are still some differences in how built - in control flow handles content projection compared to , and we will be working hard to resolve these over the next few months *ngFor. *ngSwitchBeyond that, we're confident in the implementation and stability of built-in control flow, so you can try it out today! We want to keep this in Developer Preview until the next major release so that we can work on fixes for potential backwards incompatibilities in case we find an opportunity to further enhance the development experience.

Deferrable views

Now let’s talk about the future of lazy loading! With the new block syntax, we've developed a new powerful mechanism you can use to make your applications faster. At the beginning of the blog post, I said that deferrable views take performance and development experience to the next level because they enable declarative and powerful lazy loading with unprecedented comfort.

Let's say you have a blog and you want to lazy load a list of user comments. Currently, you have to use and manage cleanup, manage loading errors, display placeholders, and a host of complex issues. Handling various edge cases can result in some complex code that will be difficult to test and debug. ViewContainerRef 

The new deferrable view allows you to lazy load a list of comments and all of their dependencies with a single line of declarative code:

@defer {
  <comment-list />
}

The most incredible part is that this all happens via compile-time transformations: Angular abstracts away all the complexity and the transitions between states by finding the components, directives, and pipes used inside the block, generating dynamic imports, and managing the loading process. switch. @defer 

There's a lot more important logic and IntersectionObserver API involved in starting a lazy-loaded component when a DOM element enters the viewport. Angular makes usage as easy as adding a deferrable view trigger! IntersectionObservers

@defer (on viewport) {
  <comment-list />
} @placeholder {
  <!-- A placeholder content to show until the comments load -->
  <img src="comments-placeholder.png">
}

In the above example, Angular first renders the content of the placeholder block. The component starts loading when it becomes visible in the viewport . Once loaded, Angular removes the placeholder and renders the component. <comment-list/> 

There are also blocks for loading and error status:

@defer (on viewport) {
  <comment-list/>
} @loading {
  Loading
} @error {
  Loading failed :(
} @placeholder {
  <img src="comments-placeholder.png">
}

That's it! Angular manages a lot of complex logic for you.

Deferrable views provide additional triggers:

  • on idle - Delay loading blocks when the browser isn't doing any heavy lifting
  • on immediate — Automatically start lazy loading without blocking the browser
  • on timer(<time>) — Lazy loading using a timer
  • on viewport and - Viewports also allow specifying references to anchor elements. Angular will lazy load the component and render it when the anchor element is visible on viewport(<ref>) 
  • on interaction and — enables you to initiate lazy loading when the user interacts with a specific element on interaction(<ref>) 
  • on hover and - trigger lazy loading when the user hovers over the element on hover(<ref>) 
  • when <expr> — Enables you to specify your own conditions via an expression that returns a promise

Deferrable views also provide the ability to prefetch dependencies before rendering them. Adding prefetching is as simple as adding statements to a defer block, and all the same triggers are supported. prefetch 

@defer (on viewport; prefetch on idle) {
  <comment-list />
}

Deferrable views are available in developer preview of v17 today! Learn more about this feature in this guide .

What's next?

Deferrable views are ready to use and we strongly encourage you to give it a try! The reason we keep them in developer preview is so we can collect more feedback and introduce changes in the API until we lock them into following semantic versioning like the rest of the framework.

Currently, server-side rendering will render the specified placeholder. Once the framework loads the application and hydrates it, deferrable views will work as we described above.

Next, we'll explore rendering content inside deferred blocks on the server and enabling partial hydration on the client. In this case, the client does not download the deferred view's code until the trigger requests it. At this point, Angular will download the relevant JavaScript and hydrate only this part of the view.

There will also be a lot of exciting signal interoperability, so stay tuned!

Improved hybrid rendering experience

Today we're ng newbringing server-side rendering (SSR) and static site generation (SSG or pre-rendering) closer to developers with tips in:

This is a change we've been wanting to make for a long time, but first we wanted the Angular SSR development experience to feel confident.

Otherwise, you can enable SSR in a new project by:

ng new my-app --ssr

Hydration is officially stable from developer preview

In the past 6 months, we've seen thousands of applications using hydration. Today, we’re excited to announce that hydration is no longer in developer preview and is enabled by default in all new apps that use server-side rendering!

New @angular/ssr package

We're moving the Angular Universal repository to the Angular CLI repository and making server-side rendering an even more integral part of our tooling!

Starting today, to add Hybrid rendering support to an existing application simply run:

ng add @angular/ssr

This command will generate the service entry point, add SSR and SSG build functionality, and enable hydration by default. Provides functional equivalents to those currently in maintenance mode . If you are using express-engine, Angular CLI will automatically update your code to . @angular/ssr  @nguniversal/express-engine @angular/ssr 

Virgin Media O2's sales increased by 112% after migrating from the old platform to the latest Angular hybrid rendering solution. By using it in conjunction with Angular SSR with DOM Hydration, cumulative layout offsets were reduced by an average of 99.4%. NgOptimizedImage 

Deploy your application using SSR

To further enhance the development experience, we work closely with cloud providers to enable smooth deployment to their platforms.

Firebase will now automatically recognize and deploy your Angular apps with near-zero configuration and provide an early preview of the new framework-aware CLI .

firebase experiments:enable webframeworks
firebase init hosting
firebase deploy

The framework-aware CLI recognizes the use of SSR, i18n, image optimization, and more, enabling you to deliver high-performance web applications on a cost-effective serverless infrastructure.

For those who have complex Angular monorepos or just prefer native tools, AngularFire allows deploying to Firebase using: ng deploy 

ng add @angular/fire
ng deploy

To enable deployment by ordinary developers, we enabled ECMAScript module support in Angular's server-side rendering, introduced a fetch backend, and worked with CloudFlare to simplify the process. HttpClient 

New lifecycle hooks

To improve the performance of Angular's SSR and SSG, we hope to move away from DOM simulation and direct DOM manipulation in the long term. At the same time, during the life cycle of most applications, they need to interact with elements to instantiate third-party libraries, measure element sizes, etc.

To achieve this, we developed a new set of lifecycle hooks:

  • afterRender — Register a callback function to be called each time the application completes rendering
  • afterNextRender — Register a callback function to be called the next time the application completes rendering. Note that the word Next means next time, which means it will only be executed once.

Only browser-related logic will call these hooks, which allows you to safely insert custom DOM logic directly into the component. For example, if you want to instantiate a charting library, you can use : afterNextRender 

@Component({
  selector: 'my-chart-cmp',
  template: `<div #chart>{{ ... }}</div>`,
})
export class MyChartCmp {
  @ViewChild('chart') chartRef: ElementRef;
  chart: MyChart|null;

  constructor() {
    afterNextRender(() => {
      this.chart = new MyChart(this.chartRef.nativeElement);
    }, {phase: AfterRenderPhase.Write});
  }
}

Each hook supports a phase value (e.g. read, write) that Angular will use to schedule callbacks to reduce layout thrashing and improve performance.

New projects use Vite and esbuild by default

Without making underlying changes to the Angular CLI build pipeline, we wouldn't be able to enable SSR in Angular in the first place!

In v16, we introduced developer previews of esbuild and Vite builds. Since then, many developers and some enterprise partners have experimented with it, reducing build times for some of their applications by 67%! Today, we’re excited to announce that the new App Builder is officially stable from Developer Preview and enabled by default for all new apps!

Additionally, we've updated our build pipeline when using hybrid rendering. With SSR and SSG, you can observe an 87% increase in speed and an 80% increase in edit refresh loop speed. ng build  ng serve 

The original picture is the animation of the bin file. The current platform does not support it. If you want to view the original text

In a future minor release, we will provide schematics to automatically migrate existing projects using hybrid rendering (client-side rendering using SSG or SSR). If you want to test out the new app builder today, check out this guide in our documentation .

Dependency injection debugging in DevTools

Last year, we showed a preview of dependency injection debugging capabilities in Angular DevTools. Over the past few months, we have implemented a brand new debugging API that allows us to plug into the framework's runtime and inspect the injector tree.


Based on these APIs we built an inspection user interface that allows you to preview the :


  • Dependencies of your components in the component inspector
  • Injector tree and dependency resolution path
    injector tree and dependency resolution path
  • Providers declared within the individual
    injectors

You can find a quick preview of the features in the animation below . Learn more about Angular DevTools on angular.io . Learn more about Angular DevTools at http://angular.io . 
    

 


Next, we will refine the UI and work on better visualizing the injector hierarchy, providers, and their resolution.

Provide independent API from the beginning

After spending the past year and a half gathering feedback on independent components, directives, and pipelines and refining the development experience for them, we are confident that we will enable them in all new applications from day one. All ng generatecommands will now build independent components, directives and pipelines.

At the same time, we've also revisited the entire documentation for Angular.io and Angular.dev to ensure a consistent learning experience, development practices, and recommendations .  

We will retain NgModules for the foreseeable future, but seeing the benefits of the new independent APIs, we strongly recommend that you gradually migrate your project to them. We also provide a schematic that automates much of the work for you:

ng generate @angular/core:standalone

For more information, check out our migration guide .

What’s next for Reactivity

Angular’s ​​new signal-based reactive system is one of the biggest shifts we’ve made in the framework. To ensure backward compatibility and interoperability with Zone.js-based change detection, we've been hard at work prototyping and designing a path forward.

Today, we are happy to announce that Angular Signals is officially stable from Developer Preview . For now, we'll keep the function in developer preview so we can further iterate on its semantics. effect 

Over the next few months, we will begin rolling out features such as signal-based inputs, view queries, and more. By next May, in Angular v18, we will have many features available to further improve the developer experience with Signals.

Next step in testing

We are continuing to experiment with Jest and ensure we build a solution that is performant, flexible, and intuitive that developers need. We also started experimenting with the Web Test Runner and submitted a PR for the initial implementation . In the near future, we may first look at Web Test Runner to unlock projects eager to move away from Karma. 

What’s next for Material 3

We've been working hard with Google's Material Design team to refactor the internals of Angular Material to incorporate design tokens , a system that will provide more customization options for components and enable Material 3 support. Although we are not yet ready to provide design token and M3 support for v17, we expect to provide these features in the v17 minor version soon.   

In Q4 2022, we announced the launch of new Angular Material components based on MDC and deprecated the old components with the same functionality but different DOM structure and style. We deprecated the old component in v15 and will remove it in v17. Even though they are not part of the Angular Material v17 packages, you can still update your application to Angular v17 and use the v16 Angular Material packages. This will be an option until v18, after which Angular Material v16 will no longer be compatible with newer versions of Angular. We also work with partners at HeroDevs who will provide endless paid support in case you are temporarily unable to perform the migration.  

Improved quality of life

In addition to all of these future-proof features, we've also got a bunch of smaller developer experience enhancements off the backlog!

Experimental view transition support

The View Transitions API  enables smooth transitions when changing the DOM. In Angular Router, we now provide direct support for this API through functions. With this feature, you cannot use the browser's native capabilities to create animated transitions between routes. withViewTransitions 

You can now add this feature to your application by configuring this feature through the router's provider declaration at application startup:

bootstrapApplication(App, {
  providers: [
    provideRouter(routes, withViewTransitions()),
  ]
});

withViewTransitions Accepts an optional configuration object with properties, a callback that gives you some extra control: onViewTransitionCreated 

  • Decide if you want to skip a specific animation
  • Add Classes to the Document to customize the animation and remove these Classes when the animation is complete
  • etc.

Automatic pre-connection in image directives

The Angular image directive now automatically generates pre-wired links for domains you provide as arguments to the image loader. The image directive will issue a warning during development if it cannot automatically identify the source and does not detect a pre-connected link to the LCP image.

Learn more about this feature in the Image Directives guide .

Lazy loading animation module

This feature reduces your initial bundle (16KB gzipped) by 60KB. Community contributor Matthieu Riegler proposed and implemented a feature that allows you to lazy load animation modules via an asynchronous provider function:  

import { provideAnimationsAsync } from '@angular/platform-browser/animations-async';

bootstrapApplication(RootCmp, {
  providers: [provideAnimationsAsync()]
});

Input value transformation

A common pattern is to have components that receive boolean input. However, this places limitations on how values ​​can be passed to such components. For example, if we have the following definition for the Expander component:

@Component({
  standalone: true,
  selector: 'my-expander',
  template: `…`
})
export class Expander {
  @Input() expanded: boolean = false;
}

...we tried using it as:

<my-expander expanded/>

You'll get an error "String cannot be assigned to boolean". Input value conversion allows you to solve this problem by configuring the input decorator:

@Component({
  standalone: true,
  selector: 'my-expander',
  template: `…`
})
export class Expander {
  @Input({ transform: booleanAttribute }) expanded: boolean = false;
}

The original feature request can be found on GitHub - Boolean Properties as HTML Binary Properties and Boolean Properties as HTML Binary Properties. 

styles and styleUrls as strings

Angular components support multiple stylesheets per component. However, the vast majority of the time, when I want to style a component, I create an array that contains a single element that points to an inline style or references an external stylesheet. A new feature lets you switch

@Component({
  styles: [`
    ...
  `]
})
...@Component({
  styleUrls: ['styles.css']
})...

to something simpler and more logical:

@Component({
  styles: `
    ...
  `
})
...@Component({
  styleUrl: 'styles.css'
})
...

We still support multiple stylesheets when you use arrays. This is simpler, more intuitive, and works better with automatic formatting tools.

Community Schematics Schematics

To support community schematic development, we provide some practical methods as part of the . You can now import expressions directly into the root of your Angular application and add providers to the root of your Angular application, as well as add dependencies to existing functions. @schematics/angular/utility  package.json 

You can learn more in the schematic guide in the documentation .

Angular developer training

We've partnered with interactive EdTech platform SoloLearn to develop new Angular training based on our recently developed ' Introduction to Angular ' course. They created an interactive learning journey that reached over 70,000 people in the past two months!

Learn more in our recent announcement .

Community Highlights

We would like to thank the 346 contributors who make Angular v17 so special! Some highlights we would like to list:

  • HttpClient now can use fetch as a backend which is one of the features enabling Angular to run in an edge worker. We'd like to thank to Matthieu Riegler for the help now can use fetch as a backend which is one of the features enabling Angular to run in an edge worker. One of the functions that runs in a thread. We would like to thank Matthieu Riegler for his help    
    HttpClient 
  • Matthieu also enabled customization , which allows specifying headers, filters, and caching for post requests HttpTransferCache 
  • Cédric Exbrayat  introduces support for namedChunks 
  • Angular Challenges  by Thomas Laforge is an excellent resource that has been helping Angular developers reach the next level  
  • AnalogJS has been steadily evolving and is approaching 1.0. Congratulations to Brandon Roberts for a job well done!  
  • Congratulations to Santosh Yadav for hitting 1 million views for his Angular Beginners course   

Building the future with Angular

Over the past six months, we've been continuing the Angular renaissance, releasing features to provide a better development experience and performance. Today, we're excited to reflect that momentum in Angular's new brand and angular.dev learning experience. 

In the next release cycle, expect a lot of evolution in Angular's signal-based reactive, hybrid rendering and learning journey.

We're honored to be a part of your journey to build your future with Angular! Thank you!

Guess you like

Origin www.oschina.net/news/272640/angular-17-released