搜游网:好玩的单机游戏下载站!
发布时间:2023-07-12 21:36:14来源:搜游网
我们知道,在使用浏览器的后退和前进按钮时,浏览器会使用缓存来优化您的页面加载过程。它显着改善了用户的浏览体验——尤其是那些网络或设备较慢的用户。作为 Web 开发人员,了解如何在所有浏览器中针对这种缓存优化页面至关重要,这样您的用户才能获得收益。
回退前进缓存是一种内存缓存,用于在用户导航离开时存储页面(包括 JavaScript 堆)的完整快照。 整个页面都在内存中,如果用户决定返回,浏览器可以快速轻松地恢复它。比如当点击返回时,在那一刻,该缓存可以对上一个页面的加载速度产生很大的影响:
下面是有缓存和没缓存的加载回退页面的过程:
回退前进缓存是如何工作的
回退前进缓存使用的“缓存”不同于 HTTP 缓存(它对于加快重复导航也很有用)。 回退前进缓存是在内存缓存中整个页面的快照(包括 JavaScript 堆),而 HTTP 缓存仅包含对先前发出的请求的响应。由于加载页面所需的所有请求都可以从 HTTP 缓存中完成是非常罕见的,因此使用回退前进缓存恢复的重复访问总是比优化得最好的非回退前进缓存导航更快。
然而,在内存中创建页面快照涉及到如何最好地保存正在进行的代码方面的一些复杂性。例如,当页面在回退前进缓存中时,如何处理超时的 setTimeout() 调用?
答案是浏览器暂停运行任何挂起的计时器或未解决的Promise——就是说会挂起所有任务队列中的任务——并在当从回退前进缓存恢复页面时恢复处理任务。
在某些情况下,这是相当低的风险(例如,setTimeout或Promise),但在其他情况下,它可能会导致非常混乱或意外的行为。例如,如果浏览器暂停了作为 IndexedDB 事务的一部分所需的任务,它可能会影响同一源中的其他打开的选项卡(因为多个选项卡可以同时访问相同的 IndexedDB 数据库)。因此,浏览器通常不会尝试在 IndexedDB 事务的中间缓存页面或使用可能影响其他页面的 API。
可以观察回退前进缓存的API
虽然回退前进缓存是浏览器自动进行的优化,但对于开发人员来说,知道它何时发生仍然很重要,这样他们就可以优化他们的页面并相应地调整任何指标或性能测量。
用于观察回退前进缓存的主要事件是页面转换事件——pageshow 和 pagehide——它们在回退前进缓存存在的时候就已经存在,并且在当今使用的几乎所有浏览器中都得到了支持。较新的页面生命周期事件(freeze和resume)也会在页面进出回退前进缓存时以及在某些其他情况下调度。
观察何时从回退前进缓存恢复页面:
pageshow 事件在页面初始加载时以及页面从缓存恢复时的 load 事件之后立即触发。 pageshow 事件有一个persisted属性,如果页面从缓存恢复,则该属性为 true(如果不是,则为 false)。 您可以使用持久化属性来区分常规页面加载和缓存恢复。 例如:
观察页面什么时候进入回退前进缓存
pagehide 是 pageshow 事件的对应事件。 pageshow 事件在页面正常加载或从缓存恢复时触发。 pagehide 事件在页面正常卸载或浏览器尝试将其放入缓存时触发。
pagehide 事件也有一个persisted属性,如果它是假的,那么你可以确信页面不会进入回退前进缓存。 但是,如果persisted 属性为真,则不能保证页面会被缓存。 这意味着浏览器打算缓存该页面,但可能存在无法缓存的因素。下面会解释几种原因,导致它可能仍然不能进入缓存并被丢弃。
为回退前进缓存优化你的页面
并非所有页面都存储在回退前进缓存中,即使页面确实存储在那里,它也不会无限期地留在那里。 开发人员必须了解是什么使页面符合(和不符合)使用缓存的条件,以最大限度地提高其缓存命中率。以下部分概述了使浏览器尽可能缓存您的页面的最佳实践。
不要使用 unload 事件
在所有浏览器中优化回退前进缓存的最重要方法是永远不要使用 unload 事件。
unload 事件对浏览器来说是有问题的,在 unload 事件触发后页面将不会继续存在。这提出了一个挑战,因为其中许多页面也是在假设用户导航离开时会触发 unload 事件的假设下构建的,这不再是真的(并且很长一段时间都不是真的)。所以浏览器面临两难境地,他们必须在可以改善用户体验的东西之间做出选择——但也可能会冒着破坏页面的风险。
如果 Chrome 和 Firefox 添加了卸载侦听器,则选择使页面不符合回退前进缓存的条件,这样风险较小,但也会取消许多页面被缓存的资格。 Safari 将尝试使用 unload 事件侦听器缓存某些页面,但为了减少潜在的损坏,它不会在用户导航离开时运行 unload 事件,这使得该事件非常不可靠。
不要使用 unload 事件,而是使用 pagehide 事件。 pagehide 事件在当前触发 unload 事件的所有情况下触发,并且当页面放入回退前进缓存时也会触发。
事实上,Lighthouse v6.2.0 添加了一个 no-unload-listeners 审计,如果他们的页面上的任何 JavaScript(包括来自第三方库的 JavaScript)添加了 unload 事件监听器,它将警告开发人员。
正确的做法:
避免 window.opener 引用
在某些浏览器(包括基于 Chromium 的浏览器)中,如果页面是使用 window.open() 或(在 88 版之前基于 Chromium 的浏览器中)从带有 target=_blank 的链接打开的——没有指定 rel="noopener"——那么 打开页面将引用打开页面的窗口对象。
除了存在安全风险之外,具有非空 window.opener 引用的页面不能安全地放入缓存,因为这可能会破坏任何试图访问它的页面。
因此,最好尽可能避免使用 rel="noopener" 创建 window.opener 引用。 如果您的站点需要打开一个窗口并通过 window.postMessage() 或直接引用 window 对象来控制它,则打开的窗口和打开器都没有资格使用缓存。
始终在用户导航离开之前关闭打开的连接
如上所述,当页面被放入缓存时,所有计划的 JavaScript 任务都会暂停,然后在页面从缓存中取出时恢复。如果这些计划好的 JavaScript 任务仅访问 DOM API(或仅与当前页面隔离的其他 API),那么在页面对用户不可见时暂停这些任务不会导致任何问题。
但是,如果这些任务连接到的 API 也可以从同一来源的其他页面访问(例如:IndexedDB、Web Locks、WebSockets 等),这可能会出现问题,因为暂停这些任务可能会阻止其他选项卡中的代码运行.
因此,某些浏览器在以下情况下不会尝试将页面放入缓存:
如果您的页面使用这些 API 中的任何一个,最好在 pagehide 或 freeze 事件期间始终关闭连接并删除或断开观察者。这将允许浏览器安全地缓存页面,而不会影响其他打开的选项卡。然后,如果页面从缓存恢复,您可以重新打开或重新连接到这些 API(在 pageshow 或 resume 事件中)。
以下示例显示了如何在使用 IndexedDB 时通过关闭 pagehide 事件侦听器中的打开连接来确保您的页面符合缓存条件:
缓存恢复后更新陈旧或敏感数据
如果您的站点保留用户状态(尤其是任何敏感的用户信息),则需要在从回退前进缓存恢复页面后更新或清除该数据。例如,如果用户导航到结帐页面然后更新他们的购物车,如果从缓存恢复过时的页面,则返回导航可能会显示过时的信息。
另一个更关键的示例是,如果用户在公共计算机上退出站点,并且下一个用户单击后退按钮。 这可能会暴露用户在注销时认为已清除的私人数据。为避免此类情况,如果 event.persisted 为 true,则最好在 pageshow 事件之后始终更新页面。
以下代码检查 pageshow 事件中是否存在特定于站点的 cookie,如果未找到 cookie,则重新加载:
测试一下保证你的页面会被缓存
Chrome DevTools 可以帮助您测试您的页面,以确保它们针对回退前进缓存进行了优化,并确定可能阻止它们符合条件的任何问题。
要测试特定页面,请在 Chrome 中导航到该页面,然后在 DevTools 中转到 Application > Back-forward Cache。 接下来单击 Run Test 按钮,DevTools 将尝试导航并返回以确定页面是否可以从回退前进缓存恢复。
如果成功,则会显示从缓存恢复成功,失败也有提示,并告诉你原因。
比如百度使用了unload导致缓存失败 :)
结语:
回退前进缓存对提高性能,及用户体验很有帮助。大家要写正确的代码来使自己的页面尽量被缓存,这样你们的网站才能大大获益。
上一篇:返回列表
第五人格游戏先知天赋怎么加点-第五人格先知怎么玩
王牌战士幽灵怎么玩
跑跑卡丁车手游制霸赛场任务攻略
崩坏3熔岩旅馆怎么通关
崩坏3精英工坊武器更新
和平精英通讯塔有什么用-和平精英通讯塔在哪
王者荣耀王者模拟战攻略-王者模拟战最强阵容玩法介绍
王牌战士据点占领怎么玩-王牌战士据点占领用什么英雄
第五人格blackjack新玩法
方舟手游辅助器
其它游戏
植物大战僵尸2恐龙危机内购破解版
其它游戏
7344游戏盒
角色扮演
gta6手机版
动作格斗
梦三国
角色扮演
末日方舟
枪战射击
一刀传世
角色扮演
cfhd
枪战射击
权力的游戏:凛冬将至
战争策略