在 Web 应用程序中设计干净、可靠的缓存的指南。当我访问一个交互非常缓慢的网站时,我会感到恼火。例如,当我们单击按钮时,该页面在几秒钟后没有反馈。我相信每个人都应该有同样的感觉。作为开发人员,如果我们开发的页面太慢,我们将面临挑战。
改善用户体验的更好方法是缓存数据。如果我们不禁用http标头的操作,浏览器将缓存静态文件。后端服务器将使用 Redis 来缓存数据,而不是直接从数据库中进行查询。在 Web 应用程序中,缓存无处不在。在 React 项目中,我们可以使用缓存组件,用于缓存函数,用于缓存数据,cache-control memo useCallback useMemo
缓存很有用。本文将介绍如何在 Web 应用程序中设计缓存,并包含以下章节:
1.如何选择存储数据的位置
2.如何管理数据的生命周期
3.如何确保缓存可靠
如何选择存储数据的位置
在Web应用程序中,存储数据的方法有很多种,我们可以通过内存,cookie,本地存储/会话存储,索引DB保存在本地浏览器中。我们还可以通过频繁的http请求将数据发布到后端服务器。
如果网站不是纯文本,通常会有以下两种类型的数据:
系统数据始终从后端服务器获取。在大多数情况下,我们需要转换数据,然后将其呈现到页面。如果转换数据非常耗时,并且可能发生多次,我们可能会将结果缓存在内存中。我们可以在 React 项目中使用,或者只使用一个全局变量来保存结果,如下面的代码所示:useMemo
您甚至可以通过使用函数属性来缓存数据:
用户操作是指用户与网站交互时的状态,如搜索数据、页面上的前进/后退、编写内容等。用户动作产生的数据在不同场景下需要使用不同的存储方式。
如果需要跨设备或浏览器访问数据,最好将其存储在后端。例如,一篇Medium文章的草稿,它将在大约5秒后发送到后端服务器,而我们停止编辑。
自动保存中等代码
如果在重新打开页面时需要恢复页面状态,则最好使用 localStorage 将其存储在磁盘中。例如,当页面支持大量过滤操作时,我们可以缓存用户的过滤项,当页面再次打开时,可以显示上次浏览的数据。
如果我们想在其他页面中共享一些数据,我们可以使用会话存储来存储它。例如,在下面的例子中,我们必须从应用程序1页面A中导航另一个应用程序2,执行一些操作,然后返回到应用程序1页面B。
如果后端服务需要感知用户的状态,建议使用 Cookie。例如用户是否命中灰度函数或ab-test。
IndexedDB用于大量结构化数据,大多数项目都不需要它,我还没有使用它。
如何管理数据的生命周期
每次创建数据时,最好考虑如何清理数据。在 JavaScript 中,我们创建变量,当不需要时,GC 会清理这些变量。当我们使用内存来缓存数据时,它将被清理。会话存储类似于内存,并在窗口关闭时清除。但是,如果我们使用cookie或本地存储,则最好考虑何时清理。
Cookie 支持设置过期时间,因此我们只需要提供过期策略。
本地存储需要手动管理生命周期。我们可以实现一个方法来做到这一点:
我们可以和一个额外的密钥来存储时间戳。当我们从localStorage获取该值时,我们将判断它是否已过期,如果过期,则将被清除。我们还可以使用该方法在挂载应用程序时删除所有过期的密钥。${key}__expires__removeExpired
如果我们的草稿数据保存在后端服务器上,最好有一个版本来记录数据
如何确保缓存可靠
最重要的是可以命中缓存,但它需要确保我们从缓存中获取的日期是正确的。例如,当我们使用对象作为本地存储的键时,将会出现意外结果:
是否已从另一个页面修改。例如,在激活选项卡时,“Medium 编辑器”页面将检查草稿是否是最新的,如果您在其他浏览器或页面中进行编辑,可能会给您一个提示:
原因是当我们发布一个对象时,localStorage的键必须是一个字符串,它将通过使用对象的属性转换为字符串。toString
首先,我们需要确保键是字符串类型,如果它不是字符串类型,我们需要提示或提供自动序列化util。
如果我们在复杂的应用程序中使用 localStorage,则需要确保缓存键是唯一的。我通常使用以下结构来命名键:
如果缓存数据将在项目或其他页面中共享,则键可能类似于 。仅当数据结构频繁更改时,版本字段才是可选的。project_feature
最后,如果我们想使用localStorage来存储函数或对象,我们需要先序列化它们,并在获取它们时反序列化它们。通常的方法是使用 JSON.字符串化和 JSON.解析,但对于函数是无用的。
结论
缓存对于页面性能非常重要。在本文中,我们将学习如何选择内存,Cookie,会话存储/本地存储或后端服务器。当我们使用缓存时,如何处理生命周期并为数据提供唯一的密钥。