V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rocmax
V2EX  ›  Next.js

新项目想尽可能 ssr,结果在时区处理上翻车了

  •  
  •   rocmax · 2024-02-01 20:39:23 +08:00 via Android · 2278 次点击
    这是一个创建于 366 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务器和 db 都是 utc ,先是统一了客户端提交的时间数据,都统一用 timestamp ,又处理了服务器和客户端渲染不一致导致的 hydration 错误。

    首屏上需要显示最近一周的统计数据,可是“最近一周”是跟用户时区相关的概念,没办法在 RSC 里预先获取数据,于是翻车了。 项目开始的时候我宣传了半天 RSC 的优势,有点骑虎难下,而且 RSC 和 server action 用上后开发和用户体验都好了不少。首屏实在不想退回到 useEffect 。

    现在能想到的一个办法是在 middleware 里返回给用户一个脚本,把 timezone 写到 cookie 里,再重定向到首页,之后按照 cookie 做 ssr 。

    本来信心满满的用上 next14 ,server action 把 API 都淘汰掉,还挺得意的。这样一个平常的问题搞了我 2 天,郁闷死了。

    16 条回复    2024-08-22 20:13:22 +08:00
    hingle
        1
    hingle  
       2024-02-01 21:02:06 +08:00
    时区是可以存放在“个人设置”里的(比如 v2 设置最后一行就有时区),这样就可以从数据库里拿了。
    rocmax
        2
    rocmax  
    OP
       2024-02-01 23:34:55 +08:00
    @hingle 感谢!
    这个项目跟其他服务共用认证服务的,用户数据从 jwt 里直接取,加项目有点困难,本服务里存的话还得搞同步。

    即使存到数据库里,服务端渲染解决了,dom 树叶子结点的客户端组件如果从顶层 RSC 层层传时区下来的话有点麻烦
    直接从浏览器取时区的话又可能有不一致的问题。
    caola
        3
    caola  
       2024-02-02 03:20:48 +08:00 via iPhone
    数据统一使用 UTC ?需要显示时再转换时区?
    rocmax
        4
    rocmax  
    OP
       2024-02-02 07:08:32 +08:00 via Android
    @caola 现在就是这个策略,问题在于 ssr 的时候不知道客户端在哪个时区,我甚至试了获取 utc-12 到 utc+14 的所有数据,在客户端 filter 这种操作
    MENGKE
        5
    MENGKE  
       2024-02-02 09:45:19 +08:00
    从客户端不可能拿到 100%正确的时间
    rocmax
        6
    rocmax  
    OP
       2024-02-02 10:26:10 +08:00 via Android
    @MENGKE 并不是追求时间正确,是用户需要看到基于当地时间的一周的数据,这就要求在 ssr 渲染之前就知道客户端的时区信息。

    如果全部按照 utc 处理反而简单了。
    MENGKE
        7
    MENGKE  
       2024-02-02 11:37:00 +08:00
    @rocmax #6 ssr 最大的目的不应该是为了 seo 和提高加载速度么,像“最近一周”这种每个用户看到的都应该是自己的和别人不一样的,我感觉完全没有做 ssr 的必要性。
    rocmax
        8
    rocmax  
    OP
       2024-02-02 11:40:09 +08:00 via Android
    rocmax
        9
    rocmax  
    OP
       2024-02-02 11:41:41 +08:00 via Android
    @MENGKE 因为最近一周这个内容它就在首页上啊,它就是影响首屏体验,不做 ssr 就只能等着转圈圈。
    rocmax
        10
    rocmax  
    OP
       2024-02-02 11:50:39 +08:00 via Android
    nextjs14 开始 ssr 的优势已经不限于首屏性能和 seo ,还有 streaming 和 boundary 等等组件粒度的渲染控制,首屏以外体验也有提升。而且开发的时候因为有了 server action 我们也舍弃了笨重的 graphql 直接用 sql 了。
    相对的,带来的最大缺点是需要区分服务端和客户端代码以及缓存控制。
    lizy0329
        11
    lizy0329  
       2024-02-02 11:53:26 +08:00
    关 ssr 什么事情?拿不到时区就渲染个 404 图片,让客户端自己搞
    Charrlles
        12
    Charrlles  
       2024-02-02 12:20:28 +08:00 via iPhone
    跟客户端有关的信息只能在客户端获取了吧,一味追求纯 ssr 也不太对。像时区这种都还可以存,如果是屏幕宽度之类跟客户端强相关,又不能储存的信息,岂不是懵圈了
    rocmax
        13
    rocmax  
    OP
       2024-02-02 13:04:46 +08:00 via Android
    最后采用的解决方法:
    middleware 里判断是否存在 cookie ,不存在的话重定向到/timezone 页面,在页面中有一个 client component ,用 Intl API 获取本地 timezone ,调用 server action 设定 cookie 并重定向回之前的页面。正在尝试做 date-fns 的函数 startOf ,endOf 系列和 format 的自适应,在服务器端根据 cookie 里的时区计算,在客户端使用原函数。

    考虑到用户所在时区不会经常变,将其设置了较长的过期时间。以后也可以在页面上搞个按钮来手动改这个 cookie 设定。

    代价是首次访问会多跳转一次,之后没有影响。
    rocmax
        14
    rocmax  
    OP
       2024-02-02 13:18:15 +08:00 via Android
    解决方案受下面这篇文章启发,本来也想直接返回 html 内容,但实际用上发现客户端并不会运行其中的 js 函数,而且好像 next12 以后不让直接修改 response body 。于是采用了跳转到空页面的办法。
    https://www.jacobparis.com/content/remix-ssr-dates
    Belmode
        15
    Belmode  
       2024-02-02 13:53:46 +08:00
    @Charrlles #12 确实是这个道理
    chenzhe
        16
    chenzhe  
       163 天前
    刚从 nextjs13 转到 nextjs14 的时候,脑子里对于哪些部分 server 哪些部分 client 安全是一团乱麻。
    写一阵子了稍微好一些了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2091 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 13:42 · PVG 21:42 · LAX 05:42 · JFK 08:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.