ajax - 使用浏览器缓存的增量更新

标签 ajax rest http caching single-page-application

客户端(一个 AngularJS 应用程序)从服务器获取相当大的列表。这些列表可能有数百或数千个元素,这可能意味着几兆字节未压缩(并且一些用户(管理员)获得更多数据)。

我不打算让客户端获得部分结果,因为排序和过滤不应该打扰服务器。

压缩效果很好(大约 10 倍)并且由于列表不经常更改,304 NOT MODIFIED 也有很大帮助。但是缺少另一个重要的优化:

由于列表的典型更改相当小(例如,修改两个元素并添加一个新元素),因此仅转移更改听起来是个好主意。我想知道如何正确地做到这一点。

GET /offer/123/items 这样的东西应该总是返返回价编号 123 中的所有项目,对吗?这里可以使用压缩和304,但是不能增量更新。像 GET /offer/123/items?since=1495765733 这样的请求听起来像是要走的路,但是浏览器缓存不会被使用:

  • 要么什么都没有改变,答案是空的(并且缓存它没有意义)
  • 或者某些东西发生了变化,客户端更新了它的状态,并且从 1495765733 之后就不再请求更改(缓存它就更没有意义了)

显然,当使用“since”查询时,不会为“资源”缓存任何内容(原始查询只使用一次或根本不使用)。

所以我不能依赖浏览器缓存,只能使用 localStoragesessionStorage,它们有一些缺点:

  • 限制为几兆字节(浏览器 HTTP 缓存可能更大并自动处理)
  • 当我达到极限时,我必须实现一些替换策略
  • 浏览器缓存存储了我没有得到的已压缩数据(我必须重新压缩它们)
  • 它不适用于用户(管理员)获得更大的列表,因为即使是单个列表也可能已经超过限制
  • 它在注销时被清空(客户的要求)

考虑到存在 HTML 5 和 HTTP 2.0,这并不令人满意。我错过了什么?

是否可以将浏览器 HTTP 缓存与增量更新一起使用?

最佳答案

我认为您缺少一件事:简而言之,标题。我认为您可以做的并且符合您的(大部分)要求的是:

  • 首先 GET /offer/123/items 正常完成,没有什么特别的。
  • 后续 GET /offer/123/items 将与 Fetched-At: 1495765733 header 一起发送,表明您的服务器在初始时请求已发送。

从现在开始,有两种可能的情况。

  • 要么没有变化,你可以发送304。
  • 但是,如果有变化,则返回新项目,因为之前发送的时间戳有 header ,但要在您的响应中设置 Cache-Control: no-cache

这使您可以进行增量更新,并缓存初始的兆字节大小的元素。

不过还有一个缺点,即缓存只进行一次,它不会缓存更新。你说你的列表不经常更新,所以它可能已经适合你了,但如果你真的想进一步插入这一点,我还能想到一件事。

收到增量更新后,您可以在后台触发另一个不带 Fetched-At header 的请求,您的应用程序根本不会使用该 header ,但只会在那里更新您的http缓存。它在性能方面应该没有听起来那么糟糕,因为您的框架不会使用新数据更新其数据(并可能触发重新渲染),唯一值得注意的缺点是网络和内存消耗。在移动设备上它可能会出现问题,但它听起来不像是一个旨在显示在移动设备上的应用程序。

我完全不知道你的用例,只是把它扔在那里,但你真的确定做某种分页是行不通的吗?对于普通人来说,要显示和处理数兆字节的数据听起来很多;)

关于ajax - 使用浏览器缓存的增量更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44192963/

相关文章:

angularjs - Angular $http.get 错误,意外 token

javascript - 如何在 ExtJ 中拦截 Ajax 响应?

java - 如何在 Rest 请求体内使用带有单字符序列构造函数/工厂方法的对象而不是单字符串构造函数?

php - 使用动态框架调整图像大小

rest - SugarCRM REST API 错误

javascript - 具有多个客户端平台的应用程序服务器 API 的 session 设计

json - 抽象 GET、读取、解码逻辑

http - 升级到 6.5 后,Gitlab 无法通过 HTTP 克隆

javascript - Rails 调用另一台服务器会出现跨源问题

javascript - 第一个 AJAX 示例无法运行