了解 BFCACHE

firefox 1.5 开始在一个浏览器会话中通过内存来缓存整个网页,包括它们的javascript状态。在已访问的页面中使用前进和后退不会触发页面加载,并且 javascript的状态都会被保留。这个特点被称为 bfcache( back-forward cache), 它使得页面导航变得更加快速。这个缓存状态将一直保留直到用户关闭了浏览器。

有些情况下,firefox不会缓存页面。下面是一些firefox不缓存页面的常见原因:

页面使用了 unload 或者 beforeload 事件句柄
页面设置了 cache-control: no-store
网站采用了Https 并且至少设置如下一条:

(1)Cache-Control: no-cache

(2)Pragma: no-cache

(3)使用了Expires: 0 或者 Expires 的值被被设置为当前页面头date属性内时间的过去时间(除非Cache-Control: max-age=同时指定)

4.页面还未加载完成用户就从页面离开,或者其他原因(XMLHttpRequest)

  1. 该页面已运行索引型数据库的事务
  2. 顶级页面中包含框架(例如iframe),且框架中有此处列举的任何一条。
  3. 页面在框架中,用户通过这个框架加载了一个新的页面(这个情况下,当用户离开这个页面,最后插入一个这个框架的内容将会被缓存)

这种新的缓存机制改变了页面加载行为,web开发者可能想:

了解一个页面是否已经访问过(什么时候页面是从缓存中加载)
当用户从离开一个页面时定义页面的行为(同时还使得页面被缓存)

两个新的浏览器事件允许开发者这么做。

##新的浏览器事件

如果你使用这些新的事件,你的页面仍然会在其他浏览器中正确显示(我们已经测试过了早期版本的firefox,ie,opera 和 safari),当页面在firefox1.5中加载时就会使用这个新的缓存机制。

注意:10–2009 safari的开发者版本中增加了对这些新事件的支持。

标准的网页行为是这样的:

用户浏览这个页面
页面的脚本在页面加载时执行
页面加载完毕后,onload句柄触发

有些页面有第四步。如果页面使用了unload或beforeunload句柄,用户离开页面时会触发它们。如果unload句柄存在,页面就不会被缓存。

当用户浏览到缓存过的页面,页面的脚本和onload句柄不会运行(第2,3步),大多数情况下,这些脚本的效果将会被保留。

如果一个页面包含部分脚本在用户每次浏览到页面时都想继续运行,或者你想知道用户什么时候浏览到了一个缓存过的页面,可以使用新的 pageshow 事件。

如果当用户离开页面时有一些行为想要触发,你想利用这个新的缓存机制但并打算使用unload句柄时,可以使用新的pagehide事件。 pageshow event

这个事件和load事件类似,不同的是这个事件在页面加载后每次都会触发。(如果页面被缓存,load事件在firefox 1.5中不会被触发)页面首次加载时,pageshow事件会在load事件触发后运行。pageshow事件包含了一个名为 persisted的属性,值是 布尔,初始化加载时,这个属性的值是false(换句话说,页面如果被缓存,这个值就是true)。

在pageshow事件触发时加入你想在页面加载时每次都执行的脚本。

##pagehide event

如果你要定义用户离开页面的行为,但是又不希望使用unload事件(unload事件会使得页面不会被缓存),你可以使用新的pagehide事 件。类似pageshow,pagehide也使用了一个名叫persisted的属性,页面如果没有被缓存,值为false,反之为true。如果这个 值为false, unload句柄会在pagehide事件触发后立即执行。

在初始化加载页面时,firefox试图以相同的顺序来触发事件。框架处理的方式与顶级文档是相同的。如果页面包含框架,那么当缓存的页面加载时:

框架中的pageshow事件会在主文档的pageshow事件之后触发
当用户离开一个缓存过的页面,框架中的pagehide事件会在主文档的pagehide事件之前触发。
框架中的页面变化时,事件只会在这个框架中触发。

无视unload和beforeunload事件缓存页面

如果你希望在使用unload或者beforeunload事件的同时保留页面缓存机制,那么你可以在回到这个页面时在pageshow事件中添加他们。

window.addEventListener(‘pageshow‘, PageShowHandler, false);
window.addEventListener(‘unload‘, UnloadHandler, false);

function PageShowHandler() {
	window.addEventListener(‘unload‘, UnloadHandler, false);
}

function UnloadHandler() {
	window.removeEventListener(‘unload‘, UnloadHandler, false);
}

示例代码

下面的示例中页面同时使用了load和pageshow事件,页面的行为如下:

在firefox1.5以外的浏览器中,页面每次加载时均会发生:load事件触发onLoad方法,同时调用onpageshow方法
在firefox1.5中,页面首次加载时,load事件与其他浏览器一样。当persisted属性为true时,只有pageshow事件会触发。
在firefox1.5中,当页面从缓存中加载时,只有pageshow事件会触发。当persisted为true时,只有在onPageShow中的脚本才会执行。

在这个例子中:

页面加载时会显示当前的时间。时间会精确到毫秒,这样你就可以很方便地测试功能。
在页面首次加载时,鼠标会定位到name字段中。在firefox1.5内,当用户返回到这个页面,光标会停留在用户离开时所在的位置,在其他浏览器中,光标将被重新放置在name字段中。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<head>
<title>Order query Firefox 1.5 Example</title>
<style type="text/css">
body, p {
	font-family: Verdana, sans-serif;
	font-size: 12px;
 	}
</style>
<script type="text/javascript">
function onLoad() {
	loadOnlyFirst();
	onPageShow();
}

function onPageShow() {
//calculate current time
	var currentTime= new Date();
	var year=currentTime.getFullYear();
	var month=currentTime.getMonth()+1;
	var day=currentTime.getDate();
	var hour=currentTime.getHours();
	var min=currentTime.getMinutes();
	var sec=currentTime.getSeconds();
	var mil=currentTime.getMilliseconds();
	var displayTime = (month + "/" + day + "/" + year + " " +
		hour + ":" + min + ":" + sec + ":" + mil);
	document.getElementById("timefield").value=displayTime;
}

function loadOnlyFirst() {
	document.zipForm.name.focus();
}
</script>
</head>
<body n">onLoad();" onpageshow="if (event.persisted) onPageShow();">
<h2>Order query</h2>

<form name="zipForm" action="http://www.example.com/formresult.html" method="get">
<label for="timefield">Date and time:</label>
<input type="text" id="timefield"><br>
<label for="name">Name:</label>
<input type="text" id="name"><br>
<label for="address">Email address:</label>
<input type="text" id="address"><br>
<label for="order">Order number:</label>
<input type="text" id="order"><br>
<input type="submit" name="submit" value="Submit Query">
</form>
</body>
</html>

与此相反,当这个页面没有监听pageshow事件,并且把所有的方法都放置在load事件中,则光标位置和时间都会被缓存。当用户返回这个页面时,显示将是缓存中的时间。

<script>
function onLoad() {
	loadOnlyFirst();

//calculate current time
	var currentTime= new Date();
	var year = currentTime.getFullYear();
	var month = currentTime.getMonth()+1;
	var day = currentTime.getDate();
	var hour=currentTime.getHours();
	var min=currentTime.getMinutes();
	var sec=currentTime.getSeconds();
	var mil=currentTime.getMilliseconds();
	var displayTime = (month + "/" + day + "/" + year + " " +
		hour + ":" + min + ":" + sec + ":" + mil);
	document.getElementById("timefield").value=displayTime;
}

function loadOnlyFirst() {
	document.zipForm.name.focus();
}
</script>
</head>

<body onload="onLoad();">

##开发firefox插件

firefox1.5的扩展需要开启这个缓存机制。当你在开发与firefox1.5及早期firefox版本兼容的扩展时,确保load事件会被缓存,pageshow事件不会被缓存。

时间: 2024-12-18 02:37:50

了解 BFCACHE的相关文章

浏览器的 bfcache 特性

一.bfcache 基本概念 现代浏览器在根据历史记录进行前进/后退操作时,会启用缓存机制,名为"bfcache"(back-forward cache,往返缓存),它使页面导航非常快.直到用户关闭浏览器,这个缓存状态才会被删除. 从 MDN 上得知,支持 bfcache 特性的 Firefox 浏览器,对于一个简单的浏览器会话,会缓存全部页面到内存中,包括他们的JavaScript状态.直到用户关闭浏览器,这个缓存状态才会被删除.bfcache 是一种浏览器优化,但是 HTML 标准

往返缓存 bfcache

很多业务中,我们从 a 页面进行操作,进入 b 页面后显示操作结果,当我们直接返回退到 a 页面时,我们需要的是 a 页面能自动刷新数据,但是,a 页面并未发生改变.也就是说,返回后页面为刷新,这就是 往返缓存  Back-Forward Cache(简称bfcache). bfcache,即back-forward cache,可称为"往返缓存",可以在用户使用浏览器的"后退"和"前进"按钮时加快页面的转换速度.这个缓存不仅保存页面数据,还保存

移动端兼容性问题解决方案

1. IOS移动端click事件300ms的延迟响应 移动设备上的web网页是有300ms延迟的,玩玩会造成按钮点击延迟甚至是点击失效.这是由于区分单击事件和双击屏幕缩放的历史原因造成的, 2007年苹果发布首款iphone上IOS系统搭载的safari为了将适用于PC端上大屏幕的网页能比较好的展示在手机端上,使用了双击缩放(double tap to zoom)的方案,比如你在手机上用浏览器打开一个PC上的网页,你可能在看到页面内容虽然可以撑满整个屏幕,但是字体.图片都很小看不清,此时可以快速

ios和android适配

一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发 解决方案:css增加cursor:pointer; 三星手机遮罩层下的input.select.a等元素可以被点击和focus(点击穿透) 问题发现于三星手机,这个在特定需求下才会有,因此如果没有类似问题的可以不看.首先需求是浮层操作,在三星上被遮罩的元素依然可以获取focus.click.change),有两种解决方案: 1.是通过层显示以后加入对应的class名控制,截断显示层下方可获取焦点元素的事件获取

移动端兼容问题注意事项

1. IOS移动端click事件300ms的延迟响应 移动设备上的web网页有300ms延迟,有时会造成按钮点击延迟或者点击失效. 苹果为了将适用于PC端大屏幕的网页能较好的展示在手机端上,使用了双击缩放(double tap to zoom)的方案,发布IOS系统搭载的safari.如:在手机上用浏览器打开一个PC的网页,你可能在看到页面内容虽然可以撑满整个屏幕,但是字体.图片都很小看不清,此时可以快速双击屏幕上的某一部分,你就能看清该部分放大后的内容,再次双击后能回到原始状态. 双击缩放:用

BOM之history对象

前面的话 history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起.由于安全方面的考虑,开发人员无法得到用户浏览器的URL,但借由用户访问过的页面列表,可以在不知道实际URL的情况下实现后退和前进.本文将详细介绍BOM中的history对象 length history.length属性保存着历史记录的URL数量.初始时,该值为1.如果当前窗口先后访问了三个网址,history.length属性等于3 由于IE10+浏览器在初始时返回2,存在兼容性问题,所以该值并不常用 histor

JS高级程序设置笔记(五)

13章:事件 JavaScript与Html之间的交互,是通过事件实现的.可以使用侦听器(或者处理程序)来预定事件. 13.1事件流: 什么是事件流:事件流描述的是从页面中接收事件的顺序. 13.1.1事件冒泡 什么是事件冒泡:可以用一个形象的比喻来描述.小鱼吐泡泡,小鱼在水里,泡泡会从水的最底部一直到水面上结束.事件冒泡和这个意思相近,IE的事件流叫做事件冒泡,是从最具体的元素开始,一直延伸到最顶层的那个结构.意思就是说,比如你创建了一个鼠标点击事件,当你点击这个元素的时候,浏览器会认为你点击

手机那点事!已有高人把常见的不常见的坑都给找出来了,我就随便转一下了

mobileTech A useful tools or tips list for mobile web application developing 这个项目收集移动端开发所需要的一些资源与小技巧 工具类网站 HTML5 与 CSS3 技术应用评估 各种奇妙的hack 几乎所有设备的屏幕尺寸与像素密度表 移动设备参数表 ios端移动设备参数速查 浏览器兼容表 移动设备查询器 移动设备适配库 移动设备适配库2 viewport与设备尺寸在线检测器 html5 移动端兼容性速查 在线转换字体 c

[移动端]移动端上遇到的各种坑与相对解决方案

mobileHack 这里收集了许多移动端上遇到的各种坑与相对解决方案 1.问题:手机端 click 事件会有大约 300ms 的延迟 原因:手机端事件 touchstart –> touchmove –> touchend or touchcancel –> click,因为在touch事件触发之后,浏览器要判断用户是否会做出双击屏幕的操作,所以会等待300ms来判断,再做出是否触发click事件的处理,所以就会有300ms的延迟 解决方法:使用touch事件来代替click事件,如