bfcache

363 阅读4分钟

问题背景

点击浏览器中的返回按钮,要让页面重新加载资源,因为这部分的资源每次去加载的内容都不一样,如果返回的时候,还是看到原先的内容,那做这个内容块的意义就很小了;如果用户看完了这部分内容,在返回来的时候,这个地方换成了新的内容,这样就能体现这部分的价值了。

定义

bfcatche,即back-forward cache,可称“往返缓存”,可以在用户使用浏览器的“后退”和“前进”按钮时加快页面的转换速度。这个缓存不仅保存页面数据,还保存了DOM和JS的状态,实际上是将整个页面都保存在内存中,如果页面位于bfcache中,那么再次打开页面就不会触发onload事件

onload事件

HTML DOM文档加载顺序

  1. 解析HTML结构

  2. 加载外部脚本和样式表文件

  3. 解析并执行脚本代码

  4. 构造HTML DOM模型

  5. 加载图片等外部文件

  6. 页面加载完毕

  7. ready:页面完成HTML的加载并建立了DOM树之后开始执行

  8. onload事件:页面加载(文本和图片)完毕的时候(第一次加载时触发,在页面从浏览器缓存中读取时不触发)

  9. unload事件:只要用户从一个页面切换到另一个页面就会发生unload事件,而利用这个事件最多的情况是清除引用,避免内存泄漏

有两种方法:

EventUtil.addHandler(window,"unload",function(){ alert("Unload"); });
<!DOCTYPE html>
    <html> 
        <head> 
            <titile>Unload Event Example</title>
        </head> 
        <body onunload = "alert('Unloaded!')"> </body> 
    </html>
  1. pageshow事件:在用户浏览网页时触发,pageshow事件类似于inload事件

  2. pagehide事件: 在用户离开网页时触发,离开网页有很多种方法,如点击一个链接,刷新页面,提交表单,关闭浏览器等。pagehide事件有时可以替代unload事件,但unload事件触发后无法缓存页面

  3. persisted属性 pageshow事件和pagehide事件的event对象还包含一个名为persised的布尔值属性

对于pageshow事件,如果网页从bfcache中加载的,则这个属性的值为true;否则这个属性的值为false。

对于pagehiden事件,如果网页在卸载之后被保存在bfcache中,则这个属性的值为true,否则这个属性的值为法;se

不同浏览器对当前窗口“打开”历史记录中的前一个页面的表现上并不统一,这和浏览器的视线以及页面本身的设置有关系

解决方案

  1. javascript监听pageshow事件阻止页面进入bfcache
window.addEventListener('pageshow' ,  function(e) {

if (e.persisted) {

window.location.reload()

}

})

在uc和微信中测试通过,但是在某些安卓手机自带的浏览器中无效

  1. js监听pagehiden事件阻止页面进入bfcache
window.addEventListener('pagehide' ,  function(e) {

var dom = document.body;

 dom.children.remove();

setTimeout(function() {

dom.appendChild("<script type='text/javascript'>window.location.reload();</script>");

});

});
  1. 设置meta标签,清除页面缓存
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>

<meta http-equiv="Pragma" content="no-cache"/>

<meta http-equiv="Expires" content="0"/>

Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下

  • Public指示响应可被任何缓存区缓存
  • Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效
  • no-cache指示请求或响应消息不能缓存
  • no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  • max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应
  • min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应
  • max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

参考

www.jb51.net/article/150… blog.csdn.net/weixin_4422…