请教一个大量 API 数据的前端缓存方案

2021-12-13 14:00:55 +08:00
 ryncv

背景是这样:公司一个后台系统,大概有四五个 API ,数据量都比较大( gzip 后大约还是有 3M )。数据内容相对稳定,不会很频繁的更新,大约一两周会更新维护一下。 如果每次访问页面都调用原始接口,会太慢,而且会占用很多下载带宽。因为一些原因,后台也没办法做成按需加载的,必须一次性全量返回。

现在方案是,第一次用户访问的时候,把接口数据全部存到 Localstorage 里面,刷新后检测到本地有数据就不请求服务器了,但是这样会存在缓存没法更新的问题,需要用户手动清理浏览器缓存。

求助一下有什么比较好的方案可以解决这个?

2764 次点击
所在节点    前端开发
29 条回复
fengfuliu
2021-12-13 14:03:43 +08:00
写个新请求每次都请求,仅下发一个字段表示是否为新数据,version:1.1 之类的
mineralsalt
2021-12-13 14:04:57 +08:00
在服务端做一个 hash 对比 api, 每次使用数据的时候, 请求 api,提交本地缓存的数据 hash, 服务端进行最新数据的 hash 比对, 如果有更新就返回 true, 本地就再缓存一次数据
wunonglin
2021-12-13 14:05:11 +08:00
那么大的数据建议放 indexeddb ,不要放 localstorage 。另外存的时候用版本号标记下(就 updated_at 就行了)。后端给接口获取这个,有变化就拉数据
mineralsalt
2021-12-13 14:05:58 +08:00
@mineralsalt 这种方案的好处是免维护, 1L 的版本方案会增加工作量
66beta
2021-12-13 14:06:59 +08:00
写到 json 文件里,将来上 CDN 也方便
wunonglin
2021-12-13 14:07:53 +08:00
@mineralsalt #4 你这个费时费力,还造成没必要的前端和后端的读取计算
mineralsalt
2021-12-13 14:09:20 +08:00
@wunonglin 辛苦一次造福未来啊, md5 一下, 也没什么计算量和工作量吧, 工具函数都是现成的, 搞版本号以后维护多麻烦
tabris17
2021-12-13 14:12:40 +08:00
静态化啊,HTTP 请求用 If-Modified-Since 头部就好了
ryncv
2021-12-13 14:12:46 +08:00
@wunonglin #3 indexdb 会比 localstorage 有明显优势吗?之前试过 indexdb ,感觉不是很稳定,有几次用户反馈看不到内容,我现场用 chrome 工具发现 indexdb 一直在转 loading 或者是直接显示白的,感觉就像初始化失败了之类的,需要把整个 indexdb 删了刷新才行。
ryougifujino
2021-12-13 14:15:25 +08:00
用协商缓存不就好了
wunonglin
2021-12-13 14:16:08 +08:00
@ryncv #9 localstorage 限制 5M 。在你不能保证数据大小的情况下(你都 3m 了,危险边缘),用 localstorage 是不保险的。再加上 indexdb 有索引之类的,可以直接取你需要的数据而不用全拿出来(当数据库用),indexdb 对于大数据来说是最优的解法
ryncv
2021-12-13 14:23:49 +08:00
@tabris17 #8
@ryougifujino #10
last-modify 的方案考虑过,但是这些数据是存在数据库里的,不是静态文件。如果需要后台实现协商缓存那一套,需要做一定的改造吧。
ryougifujino
2021-12-13 14:31:36 +08:00
@ryncv #12 后台是要稍微改一下的,但不麻烦
3dwelcome
2021-12-13 14:44:47 +08:00
协商缓存没法用啊,楼主数据集合有可能是增量更新,那就意味着可以增量下载。

而协商缓存就是简单粗暴的过期全部重下资源,没意义的,还不如自己发 hash 校验。

我以前的同事,是客户端单方面去向服务器,同步数据集合。

每条记录都有最后修改时间,只要服务器端的数据,大于客户端请求时间戳,都全部给客户端发过去。
makelove
2021-12-13 16:17:34 +08:00
我当前用的是存 indexeddb ,数据上有个自增版本号,定期用版号查后端有没有更新,有就重新下载保存。
indexeddb 各种浏览器都非常稳,就是在 safari 下有时会莫名被清了数据,非常奇怪,果然是三流内核。
ryncv
2021-12-13 16:49:36 +08:00
@makelove #15 “定期”的策略是怎样的呢? 每次进入页面先检查一下版本吗?
makelove
2021-12-13 16:54:05 +08:00
@ryncv 对,每次进都会检查,但先用旧的,如果检查结果出来有新的就直接刷新旧的显示
makelove
2021-12-13 16:58:14 +08:00
@ryncv 当然了这个还不够,还要做个定时防止有人从不关 tab ,再监控浏览器 tab 切换事件,切回来时如果有一阵没检查也去查一下
ryncv
2021-12-13 17:06:56 +08:00
@makelove 这是一个思路,感谢。
whypool
2021-12-13 17:55:00 +08:00
写个脚本把 api 跑成 json 文件丢 cdn ,改的时候前端改一下引用 json 版本,一劳永逸

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/821849

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX