V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
3dwelcome
V2EX  ›  问与答

前端用什么技术,才能合理缓存分页结果?

  •  
  •   3dwelcome · 188 天前 · 2350 次点击
    这是一个创建于 188 天前的主题,其中的信息可能已经有所发展或是发生改变。

    举个例子,AJAX 返回了 200 条电影数据,我想把数据直接缓存到前端。

    但问题是,当后台数据有更新,新数据怎么以最小的流量,以差分模式,同步到前端?

    有点类似数据库的主从备份,有什么好的参考实现吗?

    24 条回复    2022-02-02 01:52:28 +08:00
    torenayto
        1
    torenayto  
       188 天前 via iPhone
    wunonglin
        2
    wunonglin  
       188 天前
    我觉得你的实现想法有问题。原始需求是什么?
    3dwelcome
        3
    3dwelcome  
    OP
       188 天前
    @wunonglin 需求是 APP 需要展示 TOP 1000 条电影数据。

    我希望只取一次数据到客户端,数据用 WebView 给缓存起来。

    后续每次都向服务器查询有没有新数据,有的话就更新一下本地数据列表,没有的话就直接展示出来。
    3dwelcome
        4
    3dwelcome  
    OP
       188 天前
    @torenayto "https://swr.vercel.app/zh-CN"

    这确实是分页,但我这个分页在前端。

    而这网站提供的技术,好象是后端分页缓存方案。
    agagega
        5
    agagega  
       188 天前 via iPhone   ❤️ 1
    你在本地带 ID 做一个 OrderedMap ,请求的时候做 merge 就可以了。如果要实现你想的「最小的请求」,需要后端 API 也做配合,比如加一个 newer_than 参数,只返回比这个元素更新创建的所有元素。
    wunonglin
        6
    wunonglin  
       188 天前
    @3dwelcome #3 这种需求 http 缓存不就好了么。https://zhuanlan.zhihu.com/p/64694485
    vanton
        7
    vanton  
       188 天前   ❤️ 1
    传递一个 ID 列表。

    两个方案:
    1 、前端发送一个当前列表给后端,后端发送差分数据给前端。
    2 、后端发送列表,前端对比后给一个差分请求,后端返回实际数据。

    两个方案各有优势,看你是什么需求。
    wunonglin
        8
    wunonglin  
       188 天前
    @3dwelcome #3 再说。你这样要么用 http 的缓存,要么每次都要向后端请求 ver 之类的信息去检查。

    每次请求的话可以传个 map 去检查{index: id},然后返回对应新的{index: id}。然后你再比较那个电影详情数据没获取,你再单独获取那个电影的信息就行了。
    3dwelcome
        9
    3dwelcome  
    OP
       188 天前
    @vanton 我用的是第一个方案,想找一些类似参考代码,自己写差分算法,总觉得很山寨。

    可惜好像大家很少这样做,代码不太好找。
    3dwelcome
        10
    3dwelcome  
    OP
       188 天前
    @wunonglin 我是想把这个功能给抽象出来,未来适配所有的列表查询代码。

    在移动互联网时代,能减少一点网络流量,那也是好的。
    cp19890714
        11
    cp19890714  
       188 天前   ❤️ 1
    你提供的信息有点少。我只能根据我看到的提出我的方案。
    ## 后段接口:
    * 参数:updatTime-已有数据的最大更新时间。
    * 逻辑:
    1. 如果 updateTime 不是空,则查询数据时,根据 updateTime 筛选,并给出最大的 updateTime 。
    2. 如果 updateTime 是空,则响应 1000 条数据,并给出最大的 updateTime 。
    当有数据更新时,需要更新数据的 updateTime

    ## 前段
    * 首次请求,没有 updateTime 参数,会得到 1000 条数据,以及 updateTime 。
    * 下次请求,把 updateTime 传给后段,得到差异数据。并在此缓存 updateTime 。
    cp19890714
        12
    cp19890714  
       188 天前
    @cp19890714 抱歉,用平板打字,好多错字
    3dwelcome
        13
    3dwelcome  
    OP
       188 天前
    @cp19890714 updateTime 可以查询有没有新数据。

    可如果服务器删除了 1000 条里其中几条记录,怎么去通知前端也删除呢?
    enki0423
        14
    enki0423  
       188 天前 via iPhone
    @3dwelcome websocket
    cp19890714
        15
    cp19890714  
       188 天前   ❤️ 1
    @3dwelcome
    后端删除通常是逻辑删除,那么还是会有更新时间的。
    如果你的后端必须是物理删除,那么就需要传所有数据的 id ,进行对比了。
    ------------------------
    另外,我认为这个需求是伪需求。
    1. 使用压缩算法后,响应流量可以大大减少,1000 条数据,应该不会耗费多少流量。
    2. 即使每条数据有 100 个字段,流量真的较大,那么应该分为两个接口,1 个接口拿列表,1 个接口拿详情。列表接口的响应流量还是会极少,详情接口的结果进行缓存。
    lrvinye
        16
    lrvinye  
       188 天前 via iPhone
    react-query 有实现
    micean
        17
    micean  
       188 天前
    都展示 top 1k 了,就没考虑流量问题啊,也不知道考虑过 filter 的问题没有。
    维护 2 个数据集,一个是 top 1k + version ,一个是变化数据( id|action|version ),剩下的懂的
    weiyx
        18
    weiyx  
       188 天前
    swr 了解一下
    Rheinmetal
        19
    Rheinmetal  
       188 天前
    后端预先做好 delta 呗
    cyrbuzz
        20
    cyrbuzz  
       187 天前
    可以做类似 304 缓存的查询吧,询问是否有更新,有更新则把缓存的 ID 都带上给后端做对比,返回差值,然后前端更新缓存。
    3dwelcome
        21
    3dwelcome  
    OP
       187 天前
    @cyrbuzz 是的,只是这样需要前端向后端提交列表有效 ID ,也不能用 GET ,基础查询全部要改用 POST 方法。

    Restful 在流泪。
    cyrbuzz
        22
    cyrbuzz  
       187 天前
    @3dwelcome

    可以做一下改进,前端只传缓存的最新一个 ID ,后端根据传过来的 ID 查询出这个 ID 之后的内容。前端合并一下结果做下分片,在约定一个参数用来标识出改变分页大小的情况。
    fwindcore
        23
    fwindcore  
       187 天前 via iPhone
    搭一个 git 或者 svn 吧😂
    3dwelcome
        24
    3dwelcome  
    OP
       187 天前
    @fwindcore 你还别说,我还真想过类似的。

    昨晚在谷歌上找方案,顺藤摸瓜发现 nodejs 里有给 apk 打补丁的差分算法。

    分两步,第一步盲测找不同,叫 diff 。第二部打补丁,叫 patch 。

    那个算法很强,针对二进制。但是源代码太复杂了点,甚至还有专门的论文。

    最后思索半天,还是手写了一个山寨版的。两个 ID 集合不匹配总共有三种可能性,一种是旧数据覆盖更新,一种是插入新数据,一种是删除数据,都判断和处理一次就可以了。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4130 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:26 · PVG 16:26 · LAX 01:26 · JFK 04:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.