【Angular】Angular中的最差实践

news2025/1/19 3:19:29

自我介绍

  • 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【架构师酒馆】和【开发者开聊】,有更多的内容分享,谢谢大家收藏。
  • 企业架构师需要比较广泛的知识面,了解一个企业的整体的业务,应用,技术,数据,治理和合规。之前4年主要负责企业整体的技术规划,标准的建立和项目治理。最近一年主要负责数据,涉及到数据平台,数据战略,数据分析,数据建模,数据治理,还涉及到数据主权,隐私保护和数据经济。 因为需要,比如数据资源入财务报表,另外数据如何估值和货币化需要财务和金融方面的知识,最近在学习财务,金融和法律。打算先备考CPA,然后CFA,如果可能也想学习法律,备战律考。
  • 欢迎爱学习的同学朋友关注,也欢迎大家交流。微信小号【ca_cea】

简介:

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的更改检测周期之外运行代码。

  • Template | RxAngular
    
    Edit description
    
    www.rx-angular.io

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的最佳实践并避免其最坏的实践,您可以构建满足用户需求的健壮且可扩展的应用程序。所以深呼吸,保持冷静,继续学习!”

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

本文:【Angular】Angular中的最差实践 | 开发者开聊

欢迎收藏  【全球IT瞭望】,【架构师酒馆】和【开发者开聊】.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.4【共享源】克隆实战开发之截屏(二)

三,显示器截图 screen_read_display() 函数则用于捕获显示器的屏幕截图。我们需要在特权上下文中工作,以便可以完全访问系统的显示属性。我们可以通过调用具有 SCREEN_DISPLAY_MANAGER_CONTEXT 上下文类型的 screen_create_context() 来创建特权上下文。进程必须具有 root 的…

使用minio实现大文件断点续传

部署 minio 拉取镜像 docker pull minio/minio docker images新建映射目录 新建下面图片里的俩个目录 data(存放对象-实际的数据) config 存放配置开放对应端口 我使用的是腾讯服务器所以 在腾讯的安全页面开启 9000&#xff0c;9090 两个端口就可以了&#xff08;根据大家实际…

使用python对windows/win11进行属性设置

有一个个人的需求&#xff0c;针对windows系统进行属性设置&#xff0c;这里以对鼠标的左右键主键进行切换为例&#xff0c;进行了研究&#xff0c;以当前win11系统为基础进行了更动。 首先是对于如果打开windows系统下的鼠标设置&#xff0c;有以下几种办法&#xff1a; 添加…

十大经典排序算法(个人总结C语言版)

文章目录 一、前言二、对比1.排序算法相关概念1.1 时间复杂度1.2 空间复杂度1.3 排序方式1.4 稳定度 2.表格比较3.算法推荐3.1 小规模数据3.2 中等规模数据3.3 大规模数据3.4 特殊需求 三、排序算法1.冒泡排序&#xff08;Bubble Sort&#xff09;1.1 简介1.2 示例代码&#xf…

使用互斥锁(Mutex)管理共享资源

在Go中确保并发安全性 并发是Go中的一个强大功能&#xff0c;它允许多个Goroutines&#xff08;并发线程&#xff09;同时执行。然而&#xff0c;伴随着强大的功能也带来了大量的责任。当多个Goroutines并发地访问和修改共享资源时&#xff0c;可能会导致数据损坏、数据竞争&a…

网络爬虫之Ajax动态数据采集

动态数据采集 规则 有时候我们在用 requests 抓取页面的时候&#xff0c;得到的结果可能和在浏览器中看到的不一样&#xff0c;在浏览器中可以看到正常显示的页面教据&#xff0c;但是使用 requests 得到的结果并没有&#xff0c;这是因为requests 获取的都是原始的 HTML 文档…

【小白攻略】php 小数转为百分比,保留两位小数的函数

php 小数转为百分比 首先&#xff0c;最简单直观的方法是利用PHP内置的number_format函数。该函数可以对一个数字进行格式化&#xff0c;并可以设置小数点后的精度。通过将小数乘以100&#xff0c;再用number_format函数将结果格式化为百分比形式&#xff0c;即可达到将小数转为…

uniapp怎么动态渲染导航栏的title?

直接在接口请求里面写入以下&#xff1a; 自己要什么参数就写什么参数 本人仅供参考&#xff1a; this.name res.data.data[i].name; console.log(名字, res.data.data[i].name); uni.setNavigationBarTitle({title: this.name}) 效果&#xff1a;

图论 | 网络流的基本概念

文章目录 流网路残留网络增广路径割最大流最小割定理最大流Edmonds-Karp 算法算法步骤程序代码时间复杂度 流网路 流网络&#xff1a; G ( V , E ) G (V, E) G(V,E) 有向图&#xff0c;不考虑反向边s&#xff1a;源点t&#xff1a;汇点 c ( u , v ) c(u, v) c(u,v)&#xff…

CSS:浮动

CSS&#xff1a;浮动 浮动效果浮动方式 float浮动特性标准流脱标脱标的影响脱标的影响范围 清除浮动清除浮动原理 clear基于clear的清除浮动方式额外标签法:afert伪元素法双伪元素法 清除浮动原理 BFCBFC定义BFC布局规则创建一个BFC基于BFC的清除浮动方式父级添加overflow法 浮…

物理模拟重力 斜抛运动计算 抛物线计算

物理模拟重力 斜抛运动计算 抛物线计算 一、介绍二、原理三、实现如下PhysicsUtil.cs 工具类Missile.cs 四、资源分享 一、介绍 模拟Unity原始重力系统进行重写&#xff0c;可是实现发射到指定目标位置并能继续当前力进行自身的弹力与摩擦继续运动 二、原理 将Unity原始不受控…

鸿蒙开发4.0-ArkTS与H5的交互

ArkTS侧与H5的交互 首先在开发H5页面&#xff08;输入框和金额选择部分&#xff09;前需要实现JSBridge桥接打通两侧的交互。开发者可以在ArkTS侧定义一个JSBridge类&#xff0c;在类中封装call方法以及initJsBridge方法。 准备异步执行脚本&#xff0c;在脚本中声明一个JSBri…

工具系列:PyCaret介绍_Fugue 集成_Spark、Dask分布式训练

工具系列&#xff1a;PyCaret介绍_Fugue 集成_Spark、Dask分布式训练 Fugue 是一个低代码的统一接口&#xff0c;用于不同的计算框架&#xff0c;如 Spark、Dask。PyCaret 使用 Fugue 来支持分布式计算场景。 目录 1、分布式计算示例&#xff1a; (1)分类 (2)回归 (3)时间…

7.5组合总和②(LC40-M)

算法&#xff1a; 相比于上一题&#xff0c;数组candidates有重复元素&#xff0c;而要求不能有重复的组合&#xff0c;所以相对于39.组合总和 (opens new window)难度提升了不少。 如何去重&#xff1f; 先把candidates排序&#xff0c;让重复的元素都在一起 单层递归时&a…

MATLAB - 读取双摆杆上的 IMU 数据

系列文章目录 前言 本示例展示了如何从安装在双摆杆上的两个 IMU 传感器生成惯性测量单元 (IMU) 读数。双摆使用 Simscape Multibody™ 进行建模。有关使用 Simscape Multibody™ 构建简易摆的分步示例&#xff0c;请参阅简易摆建模&#xff08;Simscape Multibody&#xff09…

深度学习(七):bert理解之输入形式

传统的预训练方法存在一些问题&#xff0c;如单向语言模型的局限性和无法处理双向上下文的限制。为了解决这些问题&#xff0c;一种新的预训练方法随即被提出&#xff0c;即BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;。通过在大规模…

python通过JS逆向采集艺恩电影数据, 并制作可视化

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用: 版 本&#xff1a; python 3.10 编辑器&#xff1a;pycharm 2022.3.2 nodejs 模块使用: requests -> pip install requests execjs -> pip install…

python实现bp神经网络对csv文件进行数据预测

参考资源&#xff1a; sklearn库 bp神经网络[从原理到代码一篇搞定]&#xff08;2&#xff09;_sklearn 神经网络-CSDN博客 十分钟上手sklearn&#xff1a;安装&#xff0c;获取数据&#xff0c;数据预处理 - 知乎 (zhihu.com) 一个实例讲解如何使用BP神经网络(附代码) - 知…

基于STM32单片机智能手环老人防跌倒报警系统GSM短信上报毕业设计7

STM32单片机老人防跌倒报警系统GSM短信上报加速度7 演示视频&#xff08;复制到浏览器打开&#xff09;&#xff1a; 基于STM32单片机的智能手环老人防跌倒报警系统设计GSM短信上报ADXL345重力加速度检测设计DIY开发板套件7 修改接收短信手机号码视频&#xff1a; ★★★如何修…

Pycharm解释器的配置: System Intgerpreter 、Pipenv Environment、Virtualenv Environment

文章目录 前提1. 环境准备2. 了解虚拟环境 一、进入Interpreter设置页二、添加Interpreter1. 方式一2. 方式二 三、 System Interpreter四、 Pipenv Environment前提条件&#xff1a;详细步骤1&#xff09; 选择pipenv2&#xff09; 设置Base Interpreter3&#xff09; 设置Pip…