Skip to content

[Angular] Angular 使用心得 #33

Open
@PeterChen1997

Description

@PeterChen1997

还记得大三开始看的第一个前端框架就是 Angular,看了一周看完文档,发现啥也没看懂,并且配套的经验文章或者书籍都非常少

所以说三大框架中,学习曲线最陡峭的是 Angular,可能大家都会表示赞同,除了繁杂的概念设计较多之外,RxJS 和 TS 都是使用这个框架的必修课,如果两者不会,那么基本上寸步难行

在辅导工作时,由于对 RxJS 和 TS 基本没接触过,所以刚入职花了仅三周才开始开发第一个小需求...使用了大半年后,对于这个框架也只能说是勉强会用,离精通还差的远

发展历史

Angular 遵循语义版本控制标准,每个主要版本号都表示潜在的重大更改

Angular 承诺为每个主要版本提供 6 个月的积极支持,然后是 12 个月的长期支持

主要版本每两年发布一次,每个主要版本有 1 到 3 个次要版本

  • AngularJS
    • 初始发行 - 2010 年 10 月 20 日
    • 设计目标
      • 将 DOM 操作与应用程序逻辑分离。代码结构的方式极大地影响了这一点的难度。
      • 将应用程序的客户端与服务器端解耦。这允许开发工作并行进行,并允许双方重用。
      • 为构建应用程序的旅程提供结构:从设计 UI,到编写业务逻辑,再到测试。
    • 特点
      • 双向数据绑定
      • 依赖注入
  • Angular 2 - 2016 年 9 月 14 日发布(“Angular”不带“JS”指的是版本 2 及更高版本)
  • Angular 4 于 2016 年 12 月 13 日发布
    • 引入HttpClient,一个更小、更易于使用且更强大的库,用于发出 HTTP 请求。
    • Guards 和 Resolver 的新路由器生命周期 GuardsCheckStartGuardsCheckEndResolveStartResolveEnd
    • 加入了 NavigationStart 等现有的生命周期事件集
    • 有条件地禁用动画
  • Angular 5 于 2017 年 11 月 1 日发布。
    • 主要改进包括对渐进式 Web 应用程序的支持
    • 构建优化器和与 Material Design 相关的改进
  • Angular 6 于 2018 年 5 月 3 日发布
    • 这是一个主要版本,较少关注底层框架,更多关注工具链,以及在未来更容易使用 Angular 快速移动,例如:ng update、ng add 、Angular 元素、Angular Material + CDK 组件、Angular Material Starter 组件、CLI 工作区、库支持、Tree Shakable 提供程序、动画性能改进和 RxJS v6
  • Angular 7 于 2018 年 10 月 18 日发布
    • 关于应用程序性能、Angular Material 和 CDK、虚拟滚动、改进的选择可访问性的更新,现在支持使用 Web 标准的自定义元素的内容投影,以及关于 Typescript 3.1、RxJS 6.3、Node 的依赖更新10(仍支持节点 8)
  • Angular 8 于 2019 年 5 月 28 日发布
    • 生成的代码在运行时更易于阅读和调试
    • 更快的重建时间
    • 改进的有效载荷大小
    • 改进的模板类型检查
    • 向后兼容
  • Angular 9 于 2020 年 2 月 6 日发布
    • 版本 9 将所有应用程序移动到默认使用Ivy 编译器和运行时。Angular 已更新为可与 TypeScript 3.6 和 3.7 一起使用。除了数百个错误修复之外(wtf?),Ivy 编译器和运行时还提供了许多优势:
      • 较小的捆绑尺寸
      • 更快的测试
      • 更好的调试
      • 改进的 CSS 类和样式绑定
      • 改进的类型检查
      • 改进了构建错误
      • 改进了构建时间,默认情况下启用 AOT
      • 改进的国际化
  • Angular 10 于 2020 年 6 月 24 日发布
    • 新的日期范围选择器(Material UI)
    • 关于 CommonJS 导入的警告
    • 可选的更严格的设置
    • 与生态系统保持同步
    • 新的默认浏览器配置
    • 弃用和删除
  • Angular 11 于 2020 年 11 月 11 日发布
  • Angular 12 于 2021 年 5 月 12 日发布
    • 已弃用对 IE11 的支持

没错 NG 11 和 12 没什么改动,但是他就是升级了,嗯...

特性

脏检测

变更检测周期

  1. 开发人员更新数据模型,例如通过更新组件绑定
  2. angular 检测变化
  3. 变更检测从上到下检查组件树中的每个组件,以查看相应的模型是否已更改
  4. 如果有新值,它将更新组件的视图(DOM)

Zone.js

一般情况下,zone可以跟踪并拦截任何异步任务

Zone 通常具有以下阶段:

  • 开始稳定
  • 如果任务在区域中运行,它将变得不稳定,
  • 如果任务完成,它将再次变得稳定

简而言之,如果发生以下事件之一,则框架将触发更改检测

  • 任何浏览器事件(单击,键入等)
  • setInterval() and setTimeout()
  • HTTP 请求

尽管Angular在后台进行了大量优化,但是在大型应用程序上性能仍然会下降


变更检测策略:

  • OnPush

    • 这种更改检测策略可以 跳过对此组件及其所有子组件的不必要检查
    • 使用此策略,Angular知道仅在以下情况下才需要更新组件:
      • 输入属性已更改, 标记为@input() 的属性;

      • 该组件或其子组件之一触发事件处理程序

      • 手动触发变化检测

      • 通过异步管道链接到模板的可观察对象发出新值, 如 data | async

        让我们仔细看看这些事件类型。

  • Default

    • 每当事件触发更改检测(例如用户事件,计时器,XHR,promise等)时,此默认策略都会从上到下检查组件树中的每个组件。这种不对组件的依赖项做任何假设的保守检查方法称为脏检查。它可能会对包含许多组件的大型应用程序的性能产生负面影响。

RxJS in Angular

angular 官方使用了 RxJS 来管理和处理异步请求,这个库的理念和我们之前的 Promise 的理念完全相反,一般我们使用的是拉取的数据处理逻辑,我去 “拉” 取用户信息,然后处理展示等

而 RxJS 使用的是流的概念,是一种“推”的概念,我们将 userId 推送给用户信息请求函数,然后就能拿到用户信息,自动展示

并且 RxJS 提供了较多的内置 operator,需要一定的时间上手,但是一旦上手之后,处理起一些复杂的业务逻辑也会更加得心应手

RxJS 就是这样的一个工具,你用我推荐,我用我不用

使用心得

社区生态

有篇文章详细分析了 NG 的各种问题 ,比如

NG 的官方团队貌似出现过几次人员变更,核心成员的离开必然导致大量的维护问题 (见下方 github issues 趋势),现在 Angular 还有 1.7k 待解决的 issues..(seriously?)

Untitled

除此之外,NG 的高质量学习资料基本上可说是少得可怜,按照使用情况来看,应该是英文资料较多,实际上也很难查找到一些高质量的 NG 原理或者是是特性的深入解析文章,反而是中文的比较多,着实有些令人奇怪..

版本迭代问题

NG 不能不说的一个问题,就是版本迭代,从我使用 NG 以来,NG 就升级了两个版本,对于小型业务方来说,升级不是一个很大的问题,但是对于公司这个体量的使用者来说,问题就暴露出来了

升级的主要步骤如下

  • NG 升级:
    • 由于升级中 NG 新增或者删除了一些特性,需要一定的时间进行调整,并且测试功能的可用性,如果你不升级,你就无法使用一些你应该能使用的特性,如 HMR
  • AntD 升级
    • 升级完主框架后,需要升级 UI 框架,这里面和 NG 升级拥有者同样的问题,你需要回测所有功能
    • 并且有个很重要的点,由于 NG 的库无法或者很难向前兼容,所以库的维护方基本上只在最新的版本上修复库的问题,这就导致了用户必须升级库,才能解决自己发现的已知问题...
  • 公司内部依赖库升级
    • 如果前面都做完了,那么恭喜你,你成功了一半,接下来你就要检查项目是否能够正常启动了
    • 如果这个时候你发现有 warning,并且功能正常,那么还能接收,如果有 error,那么抱歉
    • 你需要升级依赖的库,如果依赖库的业务方没升级,那么更抱歉了,要么推动他们升级,因为在此之前你的升级都没完成
    • 如果他们不升级,那么要不自己帮助升级,或者回退上述的两个步骤,乖乖使用老版本的 NG

所以说,真的很难,求求了,别再发新版本了,没什么大变动,为啥发新版本呢,为了 KPI 吗?

坑多

  • 反直觉。在用了 React 之后发现,如果你想做一件事,用 React 可能会很绕,但是也能完成;用 NG 就会发现,很绕,而且不能完成...
  • 莫名其妙的依赖冲突。如果你使用官方的 demo, npm install 的时候就会发现有 peer-dep 冲突,太莫名其妙了...
  • 使用 FormGroup.value() 来获取 form 的 value 很正常对吧,但是如果你这么用了,你会发现少值了。disable 状态下的 formControl 的 value 不会在其中,如果需要,你得使用 FormGroup.getRawValue()....
  • this.$http.get() 为什么不能帮我把传入的非字符串对象序列化一下?为啥还得使用方自己做呢...
  • ...

微前端兼容问题

还记得说 Angular 适合大型项目的说法,到用起来,才发现根本不是这么回事

我们主站的班课项目非常之大,里面糅合了所有班课相关的模块,包括班课详情,用户详情,营销,教务等等的功能,本地 dev 需要 5 分钟,热更新 1 分钟,build 需要 40 分钟

这合理吗,这不合理...

首先,功能多了自然会带来此问题,但是 NG 官方并没有提供这类问题的解决方案,首先是不支持在项目内进行多页配置,必须得拆分项目才能拆开页面,由于项目模块的耦合,这高昂的成本, 前期也就不考虑了

后续调研发现,公司内部都在尝试迁移到 React 解决这个问题,主要有两类:

  • 使用 NG 加载 React 的组件进行渐进式迁移
  • 使用 qiankun 或者其他微前端框架进行迁移

我们本质是为了解决开发难的问题,所以组内其他小伙伴前期尝试了 qiankun 的方案,结果发现踩的坑太多,进行不下去了。最后还是回到拆分项目这一步,进度也十分缓慢

好不容易拆分得差不多了,结果公司凉了...可见这个问题的解决成本之高昂

没有 Debug Tool

Angular 没有官方可用的 debug tool,至少在 2021 年 五月为止的半年时间内,这太令人费解了

刚开始用的时候找了半天以为是没找到,所以去 github 提了 issues,发现是官方就没提供过....唯一能有的 Angury 已经在 NG9 的时候不再支持了,并且性能也很差

想念有 Vue 和 React Debug Tool 的日子...

除此之外,RxJS 也没有 debug tool,由于本身是流的概念,很多时候根本不知道,那个流出发了刷新,每次 debug,都需要加一大堆 tap tap...

很无奈,不知道这个生态的开发者是真的都已经熟悉到不需要这类工具了吗...

IDE 问题

Angular 的 IDE 兼容,目前也只有 webstorm 做的比较好,vscode 的插件基本还是不要使用了,如果还是要用 vscode,还是建议关闭所有 ng 插件,真的不好用

主要原因:

  • 性能很差
    • 跳转很慢
    • 启动后进行模块解析,风扇直接起飞
  • 插件不好用,各种没法跳转
  • ...

优缺点

  • 优点
    • 依赖注入很香。不用关心各类 service 的引入,直接在 constructor 中声明即可
    • 可复用性高。人人写的代码都长得一样
    • async pipe 很香。直接在模板中传入 userId$ | appGetUserName$ | async 即可获取用户名
  • 缺点
    • 上手成本高,前置依赖 RxJS 和 TS
    • 版本迭代太快,兼容成本太高

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions