Angular 现在进入了新的时代:无区 Angular。在这篇文章中,我们将分析 Zone 的规模有多大以及它对我们的应用程序有何影响。然后我们将看看无区的实现,并一起检查其中的差异。我个人对这个功能感到非常满意,因为 Zone.js 非常强大且稳定,而现在这个系统已经过时了。
Angular 18 使用 Zone.jsAngular 18 中使用 Zone.js, 分析打包后的代码 -> 实现一个简单的计数器功能。
初始的 Angular 项目,zone 没有压缩,大小为 113kb
Angular 18 无 Zone.js这是一个初始的 Angular 应用项目,没有使用 zoneJS 技术,大小为 23KB(未压缩)。
为什么是无区域限制?
嗯,看了那些照片之后,很清晰吧?……依我看来已经很明显了吧,但这并不是唯一的好处呢,还有其他的好处呢:
- 更好的性能:ZoneJS 使用异步任务作为变化的指示器。它并不直接知道变化发生的具体时间和位置。你可以想象这是一个始终运行且检查一切的系统,除了像 OnPush 策略等一些例外情况。
- 调试:我们都遇到过“Expression Changed After Checked”的问题。现在堆栈跟踪和错误会更直接明了。
- 更好的应用体验:我还没有找到合适的词汇来形容这个感觉,但它确实感觉更好。当你使用
async/await
或.signal()
修改属性时,变化会立即出现在正确的位置上。 - Zone.js 使得人们不愿意使用 Angular 来开发应用:想象你在构建一个用于检查用户交互的片段。例如,你想计算用户执行某些事件(如点击、触摸或键盘交互)的次数——在这种情况下,你的应用在使用 Angular 时可能会表现出不正常的行为。你需要将大量组件移出 Zone 并手动触发变更检测。否则,即使使用 OnPush 策略,应用也可能会卡住。
(注:这里的“Zoneless”是指没有特定区域划分的概念,可以简单理解为“无分区”。)
根据要求,以下是仅翻译的部分:
无区界首先,从你的 .package.json
文件中删除 zone
模块。然后不要忘记从 Angular.json
中移除 Zone polyfill
(Zone 补充)。
最后一步是在不使用 zone
的情况下设置 bootstrapApplication
。请参考 https://angular.dev/guide/experimental/zoneless#enabling-zoneless-in-an-application 获取更多关于如何在应用程序中启用无 zone
模式的详细信息。
启动应用程序(MyApp, {提供者: [
提供实验性的无区检测(),
]});
如何重构代码?
如果你遵循的是提到的外观模式(参见这里),那么你可以直接让所有方法返回信号https://angular.dev/guide/signals/rxjs-interop
- 将你的可观察对象转换为信号
- 确保你不在 HTML 中使用异步管道,而是通过组件或外观引用信号
- 然后你可以移除区域运行时和区域填充
- 然后你可以继续将逻辑从可观察对象转换为信号
- 不要忘记测试所有更改,因为行为可能有所改变
我认为没有Zone.JS的Angular会更受前端开发者们的欢迎。Zone.js对Angular产生了负面影响,使得Angular不太受欢迎,很多开发者因此转向了其他框架。另一方面,现在的Angular正变得越来越有吸引力,因为它仍保持了自己独特的架构,同时也是现代、性能优越且易于使用的框架。