之前chrome的内存占用过多的问题,一直是低配置pc的噩梦,每次用着用着就感觉卡顿很多。
Chrome 108引入了两种新模式,内存和节能,让用户可以更好地控制 Chrome 如何利用他们的系统资源。 虽然这些新模式主要是面向用户的,但它们确实有一些重要的影响,前端开发人员需要注意这些影响,因为它们可能会影响网站的用户体验。我体验了一下:
我只是开了三个tab页,通过memory saver的方式就节省了201兆,开的页面越多,效果会越明显。
打开方式是通过chrome右上角的settings进入后,选择左侧的performance,就可以开启这两个功能了:
内存保护模式
启用 Memory Saver 模式后,Chrome 会主动丢弃在后台一段时间未使用的标签页。这会为活动选项卡以及可能正在运行的其他应用程序释放内存。用户可以指示 Chrome 不要丢弃特定网站的标签。
当一个选项卡被丢弃时,它的标题和图标仍然出现在选项卡条中,但页面本身消失了,就好像选项卡已经正常关闭一样。如果用户重新访问该选项卡,页面将自动重新加载。
对于纯内容页面,丢弃和重新加载选项卡可能不会影响用户体验,但对于具有复杂用户流的丰富交互式站点,如果站点无法恢复,在该流中间重新加载可能会非常令人沮丧页面精确到用户离开的地方。
丢弃标签以节省内存是 Chrome 多年来一直在做的事情,但它只在系统内存压力大的情况下才会这样做。鉴于这种情况相对罕见,Web 开发人员可能没有意识到它正在发生。
从 Chrome 108 开始,标签丢弃将变得更加普遍,因此网站能够优雅地处理这些事件至关重要。
处理标签丢弃的最佳实践
标签丢弃对于前端开发人员来说并不是一个新的挑战。用户总是有可能在完成任务之前有意或无意地重新加载页面。因此,对于网站来说,存储用户状态一直很重要,这样他们就可以在用户离开和回来时恢复它。
最重要的考虑因素不是是否存储用户状态,而是何时存储。这一点很关键,因为当选项卡被丢弃时,不会触发任何事件,因此开发人员无法对正在发生的事件做出反应。所以,开发人员需要预见到这种可能性并提前做好准备。
存储用户状态的最佳时间是:
- 随着状态的变化周期性地。
- 每当标签背景(
visibilitychange
事件)时。
存储状态最糟糕的时间是:
- 在
beforeunload
事件回调中。 - 在
unload
事件回调中。
可以参考页面生命周期事件图,以查看当页面被丢弃时预计会触发哪些事件。从该图中可以看出,选项卡可以从“隐藏”状态变为“丢弃”状态,而无需触发任何事件。
事实上,任何时候页面处于“隐藏”状态,都无法保证在页面被浏览器丢弃或被用户终止之前会触发任何其他事件,这就是为什么始终存储任何未保存的内容很重要事件中的用户状态visibilitychange
,因为可能不会再有机会了。
以下代码概述了一些示例逻辑,用于在当前用户状态发生更改时排队持久化,或者在用户将选项卡设置为背景或导航离开时立即排队:
let state = {};
let hasUnstoredState = false;
function storeState() {
if (hasUnstoredState) {
// Store `state` to localStorage or IndexedDB...
}
hasUnstoredState = false;
}
export function updateState(newState) {
state = newState;
hasUnstoredState = true;
requestIdleCallback(storeState);
}
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
storeState();
}
});
检测到标签被丢弃
如前所述,无法检测到选项卡即将被丢弃,但可以在用户返回并重新加载页面后检测到选项卡已被丢弃。在这些情况下,document.wasDiscarded
属性将为真。
if (document.wasDiscarded) {
// The page was reloaded after a discard.
} else {
// The page was not reloaded after a discard.
}
这一部分对前端监控平台非常重要,如果sdk中没有怎么对此逻辑进行处理,会出现的问题就是切到被丢弃的便签页时,其实并不是用户主动进行的访问或者刷新,会导致pv的数据过多。
在内存保护模式下测试站点
可以通过加载页面然后chrome://discards
在单独的选项卡或窗口中访问来测试页面如何处理被丢弃的问题。
在chrome://discards
UI 中,可以找到要从列表中丢弃的选项卡,然后单击操作列中的紧急丢弃。
这将丢弃该选项卡,允许您重新访问它并验证页面是否已重新加载到与您离开时相同的状态。
请注意,目前还没有一种方法可以通过 webdriver 或 puppeteer 等测试工具自动丢弃标签;但是,由于选项卡丢弃和恢复几乎与页面重新加载相同,如果您测试用户状态在用户流中间重新加载后恢复,它可能也适用于丢弃/恢复。两者之间的主要区别是beforeunload
、pagehide
和unload
选项卡被丢弃时不会触发事件,因此只要不依赖这些事件来保持用户状态,就可以使用重新加载来测试丢弃/恢复行为。
节能模式
启用节能模式后,Chrome 会通过降低显示刷新率、影响滚动和动画保真度以及视频帧速率来节省电池电量。
一般来说,开发者不需要做任何事情来支持 Energy Saver 模式。用于动画和过渡的 CSS 和 JavaScript API ,并且requestAnimationFrame()
在启用此模式时将自动调整以适应显示刷新率的任何变化。
这种模式可能出现问题的主要场景是,如果站点使用基于 JavaScript 的动画,这些动画为所有用户假定特定的刷新率。
例如,如果站点使用requestAnimationFrame()
循环并假设回调之间恰好经过 16.67 毫秒,则在启用节能模式时,动画运行速度将减慢两倍。
测量显示刷新率
没有专门的 Web API 来测量显示刷新率,一般来说,不建议尝试使用当前的 API 进行测量。
开发人员可以对现有 API 做的最好的事情是比较连续requestAnimationFrame()
回调之间的时间戳。虽然这在大多数情况下适用于近似给定时间点的刷新率,但它不会让你知道刷新率何时发生变化。为此,必须不断进行requestAnimationFrame()
投票,这违背了为用户节省能源或电池寿命的目标。
在节能模式下测试站点
在节能模式下测试网站的一种方法是在 Chrome 的设置中启动该模式并将其配置为在设备拔下时运行。
如果没有可拔出的设备,也可以按照以下步骤手动启用该模式:
- 启用
chrome://flags/#battery-saver-mode-available
标志。 - 访问
chrome://discards
并单击Toggle battery saver mode链接(重要:#battery-saver-mode-available
需要启用该标志才能使链接正常工作)。
启用后,可以与站点进行交互并验证一切看起来是否正常:例如,动画和过渡是否以所需的速度运行。