浏览器后退按钮在 Safari 和 Chrome 中以不同方式处理脚本更改

Browser back button treats scripted changes differently in Safari and Chrome

对于耗时的导航(在 Python/Flask 后端实现), 很高兴有视觉反馈 表明下一页预计需要一些时间来加载, 即使只是快速 DIY devops 脚本。 以很少的技术开销实现这一目标 我已经实现了这样的加载消息:

<script type="text/javascript">
    function loading(){
        document.getElementById("loading").style.display = 'block';
        document.getElementById("content").style.display = 'none';
    }
</script>

<body>
    <div id="loading" class="invisible"> <!-- display: none; -->
        Loading ...
    </div>
    <div id="content">
        <a href="/time/consuming/service/call" onclick="loading();">Work miracles.</a>

(感谢中的一些答案 another SO question ...)

在所有浏览器中向前导航都非常有效,但在使用浏览器向后导航时 来自(当前)Safari 或 Firefox 中目标页面的按钮,我最终得到“正在加载...”, 因为当从浏览器缓存中重新加载页面时 display: none; 被保留。 在 Chrome 中,浏览器后退按钮在这种情况下工作正常(这可能会引发问题 在其他用例中,当用户希望看到页面处于他们离开时的状态时)。

所以我想我在这里遗漏了一些东西。 如何强制后退按钮加载状态下的缓存代码 浏览器正在加载最后一页而不是它离开时的状态?

实际上我缺少的是所谓的“Back/forward 缓存”或bfcache。作为性能优化,bfcache 存储页面的完整快照,包括我的小 JavaScript 在 Safari 中所做的更改,但在 Chrome 中没有。

事实证明,我们可以轻松地对 bfcache 事件作出反应:

<script type="text/javascript">
    function loading(){  // replace content by Loading ...
        document.getElementById("loading").style.display = 'block';
        document.getElementById("content").style.display = 'none';
    }
    function makeContentVisisble() {  // replace Loading ... by content
        document.getElementById('loading').style.display = 'none';
        document.getElementById('content').style.display = 'block';
    }
</script>

<body onpageshow="makeContentVisisble()"> <!-- called on browser back -->
    <div id="loading" class="invisible">
        Loading ...
    </div>
    <div id="content">
        <a href="/time/consuming/service/call" onclick="loading();">Work miracles.</a>

这样浏览器后退在 Chrome 和 Safari 中都能顺利(并且快速,无需从后端重新加载页面)。

在这个 2020 年的失败当前博客中找到有关 bfcache 的更多详细信息:https://web.dev/bfcache/