前言

上次在弄solitude主题的CMD打字机效果时,用了 localStorage 来持久化存储打字进度。现在给新网站加音乐播放器模块时,也需要存播放进度——当前播到第几首、播到几分几秒、音量大小等。

但这次我没有用 localStorage,而是选了 sessionStorage。为什么?这篇文章就来对比一下两者的区别,以及在实际项目中的选择。

回顾 localStorage

在前一篇文章《使用浏览器的localStorage功能存储数据》中,我详细介绍了 localStorage 的用法。简单回顾一下核心特点:

  • 持久化存储:数据没有过期时间,关闭浏览器后重新打开,数据依然存在
  • 跨标签页共享:同源下所有标签页都能读写同一份数据
  • 容量较大:一般支持 5-10MB
  • 手动清理:数据不会自动消失,需要手动调用 removeItemclear

CMD 打字机效果用了 localStorage 是合理的,因为用户下一次打开网站时,应该从上次的进度继续打字,而不是从头开始。

什么是 sessionStorage

sessionStoragelocalStorage 同属 Web Storage API,API 几乎一模一样:

// 存储
sessionStorage.setItem('key', 'value');
// 读取
sessionStorage.getItem('key');
// 删除
sessionStorage.removeItem('key');
// 清空
sessionStorage.clear();

但它有一个关键区别:数据只在当前浏览器会话期间有效。一旦关闭标签页或浏览器窗口,数据就会被清除。

sessionStorage 的核心特点

特性sessionStoragelocalStorage
生命周期关闭标签页即清除永久保留
跨标签页共享❌ 每个标签页独立✅ 同源共享
存储容量~5MB~5-10MB
页面刷新✅ 数据保留✅ 数据保留
前进/后退✅ 数据保留✅ 数据保留
Ctrl+N 新窗口❌ 数据不共享✅ 数据共享

注意:sessionStorage 在页面刷新(F5)和前进后退时数据不会丢失,但复制标签页(Duplicate Tab)或 Ctrl+N 打开新窗口时会创建新的会话。

为什么音乐进度用 sessionStorage 而不是 localStorage?

这是一个关键的选型决策,有以下几个理由:

1. 生命周期更合适

用户关闭标签页后,音乐播放进度就”过期”了——下次打开网站时,大概率不是想要从上次的歌单第 3 首继续播。用 sessionStorage,关闭标签页就自动清理,干净利落。

而 CMD 打字效果不一样,那个进度需要”永久记忆”,所以用 localStorage

2. 避免跨标签页冲突

localStorage 的数据在同源的所有标签页间共享。如果用户打开了两个网站标签页,两个页面都往同一个 Key 写播放进度,就会互相覆盖,导致混乱。

sessionStorage 每个标签页独立存储,互不干扰。用户可以在两个标签页分别播放不同的歌曲,进度各自管理。

3. 刷新页面时保留体验

这是 sessionStorage 相对普通变量的优势:用户按 F5 刷新页面后,播放进度不会丢失,可以无缝继续。

4. 自动清理,不占空间

sessionStorage 关闭标签页自动清除,不需要手动管理清理逻辑。localStorage 如果不做清理,日积月累会占满配额。

两种存储的选型总结

场景推荐方案原因
主题/语言偏好localStorage需要持久记忆用户偏好
CMD 打字进度localStorage下次打开要继续
音乐播放进度sessionStorage会话级别即可,避免跨标签页冲突
表单草稿保存localStorage防止意外关闭丢失
视频/音频当前时间sessionStorage会话级,刷新不丢失
API 数据缓存localStorage减少请求,长期有效
临时 UI 状态(如弹窗是否显示过)sessionStorage本次会话记录即可
登录 Token都不合适httpOnly Cookie 更安全

小结

sessionStoragelocalStorage 用起来几乎一样,区别仅在于生命周期和跨标签页共享策略。选型的关键是问自己两个问题:

  1. 下次打开浏览器还需要这数据吗? 需要 → localStorage,不需要 → sessionStorage
  2. 多个标签页需要共享这数据吗? 需要 → localStorage,不应该共享 → sessionStorage

音乐播放进度两个问题都是需要,所以 sessionStorage 是最佳选择。CMD 打字机效果的进度两项都是肯定,所以选了 localStorage