在 Ember Octane 中缓存的最佳方法

Best approach to caching in Ember Octane

我有一个项目运行 Ember@3.20。我们目前正在从基于经典的组件迁移到基于微光的组件,并且遇到了一些可以从缓存中受益的昂贵计算模式。

我的问题是,对于 glimmer 组件,将功能缓存到 getter 的最佳方法是什么?看起来目前有几种方法可以做到这一点:

  1. @cached via tracked-toolbox - 我相信这是在 ember 缓存 api 之前发布的。我没有偷看引擎盖下,但它有一个 @cached 装饰器,可能会与未来发生冲突 ember @cached.
  2. ember-cache-primitive-polyfill - Mentioned in the Ember docs 作为 ember 缓存 API (3.22) 的 polyfill,但语法不如 @cached 装饰器[=30] 简洁=]
  3. ember-cached-decorator-polyfill - related to RFC566 似乎基于选项 2,语法更符合人体工程学
  4. 升级到 3.22 - 尝试避免碰撞 ember 除非有明显的好处。乍一看,我没有看到这里包含@cached。

任何额外的 insight/guidelines 关于 getter 应该多昂贵才能保证它被缓存?例如,防止重新渲染似乎是一个相当明显的用例,但开发人员可能认为“昂贵”的计算范围很广。

这里有两类东西:

  1. 两个 @cached 装饰器。
  2. 通过RFC 0566引入的缓存原语。

在绝大多数 Ember 或 Glimmer 应用程序或普通库代码中,您只会使用装饰器。如果您自己构建一些低级库代码(不是 never,但不完全是 common,您只会真正接触到缓存原语, 或者).

至于 @cached 装饰器,它们基本上 具有相同的语义。跟踪工具箱版本是为 Glimmer 发布(和 Ember 使用)的原语开发提供的研究,因此 ember-cached-decorator-polyfill 是使用实际的 public API—如有必要,通过 ember-cache-primitive-polyfill 填充它。


就性能特征而言,您实际上甚至不需要考虑防止重新渲染:反正系统不是这样工作的。 (请参阅 this blog post I wrote last year (2020) 深入了解如何在 Ember 和 Glimmer 中使用自动跟踪概念安排重新渲染。)同样值得记住的是,缓存不是免费的!所以它并不像“这东西要花点钱,所以我应该缓存它”那么简单——缓存必须为自己付出代价才值得,而且它会消耗内存和 CPU 创建和检查缓存的时间.

牢记这个警告,我倾向于将这里的“费用”分为以下几类:

  • 我要渲染成百上千次吗?
  • 渲染是否会导致长时间的运行计算影响渲染(即几毫秒的数量级)
  • 这会触发异步行为吗?
  • (especially) 这会触发 API 调用吗?

在很多普通的应用程序代码中,您真正需要用 @cached 修饰的唯一 getter 是 getter 产生 API 调用的关于组件的参数。由于 getter 每次被引用时都会被调用,因此您最终会得到多个 API 调用,这可能会导致 UI 中的表观状态来回翻转作为对不同承诺的引用解决。