首页 > 解决方案 > 如何为 Angular SPA 实现缓存

问题描述

我正在开发带有 ASP.NET 核心后端的 Angular 7 应用程序。应用程序托管在 Azure 应用服务中,SQL 数据库也在那里。我注意到有些表很少更改,例如国家表,但另一方面,我需要在我的 SPA 中经常使用它们。我想知道哪种缓存解决方案适合我的情况。

到目前为止,我还没有尝试过任何具体的东西。据我了解,如果我在 SPA 端缓存国家/地区,我将无法访问新添加的国家/地区(有时会发生这种情况),直到用户重新加载页面并重新启动应用程序。我知道像 Redis 缓存这样的服务可以解决这个问题,但它非常昂贵。由于 Azure App 服务可以扩展,我想我也不能使用像 SignarR 这样的解决方案。我正在考虑使用推送通知,例如,https://www.telerik.com/blogs/push-notifications-in-asp-net-core-with-angular

我想听听我的担忧是否正确,这是一个推荐的解决方案,有优点和缺点,请:)

标签: angularcachingasp.net-coresingle-page-applicationazure-app-service-envrmnt

解决方案


我相信你有 Dot net core api 调用来获取国家列表。在我看来,您应该缓存实际获取国家/地区列表的 api 调用。

尽管这些应用程序都是数据驱动的并且看起来非常动态,但在同一个用户会话中真正发生的变化并没有那么多,但无论如何我们都在为新内容发出 http 请求。

最简单的解决方案是缓存 缓存在哪里?在服务器上?但这并不能阻止我们所有的应用程序访问我们的服务,从而增加它们的负载。

也许我们可以使用服务工作者,因为它允许缓存 API 调用?是的,这是选项之一,因为它已经与 Angular 进行了很好的集成,并允许一个简单的解决方案来选择性地缓存资源和 API。但是,我们想要的是不仅能够选择要缓存的内容,还能够选择何时缓存。

我们实际上可以缓存所有 API 调用结果,但前提是我们确定数据源没有以某种方式发生变化。

如果您使用 Angular 和 Typescript,并且我们所有的数据调用都通过 RxJs,我们可以创建一个 Cache Observable 装饰器,我们将使用它来仅将缓存功能赋予某些方法。

前:

getCountry(take?: number, skip?: number) {
    return this.http.get(
      `${environment.api}/Country/latest?take=${take}&skip=${skip}`
    );
  }

它会变成:

@Cacheable({
    cacheBusterObserver: CountryNotifier
  })
  getCountry(take?: number, skip?: number) {
    return this.http.get(
      `${environment.api}/Country/latest?take=${take}&skip=${skip}`
    );
  }

请注意,@Cacheable() 仅应用于我们想要的方法,并且还传递了 cacheBusterObserver,这基本上是我们基于 Subject 的机制,当在该流中发出任何值时,它会告诉这个精确修饰的方法来释放其所有缓存。

例如,下面的方法将“缓存破坏”上面方法的缓存,如果它返回的 Observable 发出一个值

@CacheBuster({
    cacheBusterNotifier: countryNotifier
  })
  saveCountry(id: string, name: string, review: string) {
    return this.http.put(`${environment.api}/Country`, {
      id,
      name,
      review
    });
  }

这可能是最复杂的示例,但我们还实现了其他配置,例如 maxCacheCount、maxAge、slidingExpiration 和自定义缓存决策器和解析器,它们使我们能够对缓存的内容、时间和方式进行细粒度控制。


推荐阅读