解决跨时区 Nuxt SSR 导致的页面离奇 Bug

💡 原文中文,约1900字,阅读约需5分钟。
📝

内容提要

这篇文章讲述了作者在解决一个奇怪的bug时遇到的问题,发现在午夜过后打开网页时界面渲染异常。经过调试,发现该bug与时区有关。最终,作者解决了这个bug,并意识到处理时区在全球化应用开发中的重要性。

🔎

延伸解读

时区差异如何引发 SSR 渲染异常

文章指出,服务器位于美西时区,而用户位于+8时区,导致服务器端渲染时对日期的判断与客户端不一致。服务器认为日志是当天写的,而客户端认为已是第二天,从而在 hydration 过程中出现 HTML 复用和修改的冲突,最终导致界面渲染异常。这提醒开发者,SSR 中任何依赖本地时间的逻辑都可能因时区不同而产生分歧。

难以复现 Bug 的典型特征与排查思路

作者总结了该 Bug 的几个特征:只在午夜后出现、只在刚发布日志后出现、只在新加载页面时出现、只在线上环境出现。这些条件叠加使得本地开发环境难以复现。排查时,作者建议查看源代码而非 DOM 树,因为 DOM 可能已被 Vue 修改,而源代码能反映服务器端渲染的初始结果,有助于发现时区导致的不一致。

利用 Vercel 请求头获取用户时区

解决方法是使用 Vercel 提供的 useRequestHeader('x-vercel-ip-timezone') 获取用户所在时区,并确保整个 SSR 在该时区下进行。作者使用 dayjs 的 timezone 功能,在所有 dayjs() 调用后加上 .tz(tzHeader),从而统一服务器和客户端的时间判断。这为部署在 Vercel 上的全球化应用提供了一种可行的时区处理方案。

全球化应用开发中的时区处理启示

作者通过这个案例意识到,处理时区在全球化应用开发中至关重要。尤其是使用 SSR 时,服务器和客户端可能处于不同时区,任何涉及日期、时间或“今天/昨天”判断的逻辑都需要显式指定时区。否则,类似午夜后渲染异常的问题可能反复出现,且难以调试。建议在项目早期就统一时区处理策略。

❓

Q&A

这个bug是什么时候出现的?

这个bug在午夜零点之后出现。

导致这个bug的主要原因是什么?

导致这个bug的主要原因是时区差异,服务器端渲染的结果与本地效果不一致。

如何解决这个跨时区的bug?

解决方案是使用Vercel提供的时区信息,确保SSR在正确的时区进行。

这个bug对用户体验有什么影响?

这个bug导致网页界面渲染异常,影响了用户对数据的正确理解。

作者在解决bug的过程中有什么收获?

作者意识到处理时区在全球化应用开发中的重要性。

使用什么工具来处理时间和时区?

作者使用了dayjs来处理时间,并利用其自带的timezone功能。

🏷️

标签

➡️

继续阅读