跳转到主要内容

简介:

Angular是构建web应用程序的一个流行而强大的框架,但与任何技术一样,它也有一些糟糕的做法。作为一名开发人员,重要的是要意识到这些最糟糕的做法,这样你就可以避免它们,并编写可维护、高性能和可扩展的代码。

在本文中,我们将探讨Angular开发中一些最常见的最差实践,并提供解决方案和最佳实践。

因此,让我们深入学习如何避免Angular开发中的这些常见错误

请深呼吸,保持耐心。

1.不要清除您的订阅:

这是一种非常常见的做法,可能会导致内存泄漏🤯🤯

constructor(private userService:UserService){}

onInit(){
this.userService.user$.subscribe(user=>{...})
}

当您在Angular中订阅Observable时,您正在Observable和订阅者之间创建连接。

Observable将继续发出值,直到您取消订阅它,即使订阅它的组件不再使用。

要解决此问题,只需使用其中一个:

  • takeUntil()
  • take()
  • takeUntilDestroy()
  • subscription.unsubscribe()
  • async Pipe

2.在每个位置使用类型“any”

当您使用“any”类型时,您将失去TypeScript强大的键入系统的优势,该系统有助于捕捉错误并提供更好的代码完成和文档。此外,使用“any”可能会使代码更难理解和调试。

/** using any **/
user:any

/** using specifc type **/
interface User{
id:string;
name:string;
age:number;
}
user:User

通过使用特定的类型,您可以确保您的代码是类型安全的,并且更易于理解和维护。

所以请使用TypeScript而不是JavaScritp🙏🙏🙏

3.将静态字符串作为属性绑定到Html元素

有时您可能需要为Angular中的Html元素提供一个静态值。一种方法是使用方括号表示法绑定一个静态字符串作为输入,如下所示:

<input [placeholder]="'hello'">

虽然这将按预期工作,但可能会导致不必要的性能问题。

当使用方括号绑定输入时,Angular将输入视为动态属性,需要在每个更改检测周期中进行检查。这意味着Angular将执行额外的工作来检查输入,即使值永远不会改变。

为了避免这个问题,您可以简单地将静态值作为常规输入传递,而不使用方括号表示法,如下所示:

<input placeholder="hello" >

4.在“滚动||鼠标移动…”事件上使用Hostlistner或EventBinding

需要注意的是,对每个事件触发更改检测也会导致性能问题,尤其是当您正在侦听频繁触发的事件时,如mousemove或scroll事件

<div (scroll)="onscroll()">....</div>

要修复此问题,您可以使用NgZone服务在Angular的更改检测周期和手动更改检测之外运行事件侦听器。

/** template **/ 
<div #el>...</div>

/** component **/
@ViewChild('el',{static:true})el:ElementRef;

constructor(private zone:NgZone,prviate cdr:ChangeDetectorRef){}

OnInit(){
 this.zone.runOutsideAngular(()=>{
  fromEvent(this.el.natvieElement,'scroll').subscribe((e)=>{...
    if(...){
     ...
     this.cdr.detectChange()  
     }
   })
 })
}

在处理事件侦听器时,优化应用程序性能的另一种方法是使用RxAngular,这是Angular中的一个反应式编程库,提供了一些优化性能的功能。RxAngular的一个功能是区域修补运算符,它允许您在Angular的更改检测周期之外运行代码。

5.在应用模块中导入共享模块

在AppModule中导入SharedModule时,SharedModule中的所有组件、指令和管道都包含在主捆绑包中,即使它们没有在AppModule内使用。这可能会导致捆绑包大小不必要地增加,从而导致加载时间延长和性能降低。

@NgModule(
{...
imports:[SharedModule,...]
})
export class AppModule { }

只需避免将其导入AppModule或其中的任何嵌套模块即可解决此问题。相反,您应该只在需要使用其共享组件的功能模块中导入SharedModule。

注意:在Angular开发中,使用独立组件可能是一种很好的做法

6.在多个模块中导入CoreModule

CoreModule是一个模块,它包含在整个应用程序中使用的服务、提供程序和其他全局配置。它通常只在AppModule中导入一次,不应在任何其他模块中导入。

如果在多个模块中导入CoreModule,实际上就是在创建相同服务和提供程序的多个实例,这可能会导致意外行为和错误。这也可能导致循环依赖,即模块以无法解决的方式相互依赖。

为了避免此问题,您应该只在AppModule中导入一次CoreModule。如果您需要使用CoreMod的服务或提供商

OnInit(){
/* JavaScript function*/
setInterval(()=>{
  ...
  },1000)
/*Rxjs oprators*/
const subscription=interval(1000).subscribe(()=>{...})
}

像eventBinding一样,您需要在区域外运行代码并手动检测更改。

8.不要将代码拆分为多个组件

如果不将代码拆分为多个组件,那么最终可能会得到一个做太多事情的大型单片组件。这可能会使代码的维护和重用变得更加困难,如果组件变得过于复杂,也可能导致性能问题。

为了避免这种糟糕的做法,您应该尽可能将代码拆分为多个组件。每个组件都应该设计为处理特定的功能或用户界面元素,并且应该是可重用和可维护的。

9.使用默认更改检测策略

默认更改检测策略是Angular中最常用的策略,它适用于大多数应用程序。使用默认策略时,Angular会将组件输入和内部状态的当前值与其以前的值进行比较,然后更新vie

默认更改检测

虽然默认更改检测策略适用于大多数应用程序,但在某些情况下性能可能较差。例如,如果一个组件有许多频繁更改的输入,这可能会触发不必要的更改检测周期,并影响应用程序的性能。

onpush change detection

OnPush更改检测策略是一种优化更改检测的方法,它只在组件的输入发生更改或触发事件时检查组件的输入。这可以帮助减少不必要的更改检测周期,并提高应用程序的性能。

10.将ShareReplay与所有请求一起使用

shareReplay是一个RxJS操作符,允许您与订阅者共享可观察结果,这样他们就不必重新执行可观察结果。虽然shareReplay可用于缓存和优化性能,但将其用于所有请求可能会导致问题,因为它可能会用缓存的数据填充内存。

constructor(private listService:ListService){
  this.list$=this.listService.getList().pipe(shareReplay())
}

正确使用它以避免这些问题是很重要的。

以下是一些最佳实践:

  1. 仅在必要时使用shareReplay
  2. 使用缓存超时
  3. 使用有限的缓存大小
  4. 在上没有订阅时使用refCount清除缓存

最后:

在应对挑战和寻找解决方案时,请记住对自己和框架保持耐心。在没有完全理解其含义的情况下,不要匆忙浏览代码或进行快速修复,因为这可能会导致意外的错误和性能问题。

通过花时间了解Angular的最佳实践并避免其最坏的实践,您可以构建满足用户需求的健壮且可扩展的应用程序。所以深呼吸,保持冷静,继续学习!”

希望你觉得这很有用,如果你对此有任何意见,或者你有其他不好的做法可以与我们分享,请告诉我。

有用的资源: