在用户普遍3g网络的条件下,如何加快用户对于游戏体验是非常重要的。一般对于资源加载采取的方式主要是懒加载、预加载和缓存。对于h5游戏需要对游戏资源加载进行预加载,同时需要对于这些相对不会变更的资源进行缓存,这样用户二次进入的话,就不会浪费太多少时间在等待。针对这种缓存,本文就
Cache进行调研测试
1、Cache
浏览器的缓存主要有memoryCache、diskCache、ServiceWorker cache,本文主要以ServiceWorker cache为主。缓存存储的结构数据,主要是一种包含请求和响应的存储格式。当用户访问当前页面时,浏览器会发出若干请求,服务器端响应内容是HTML 结构,或结构化数据,或其他媒体资源等。cache缓存允许浏览器本地存储这些请求和响应。
- 注意:
- a、Cache 接口像 workers 一样,是暴露在 window 作用域下的。尽管它被定义在 service worker 的标准中,但是它不必一定要配合 service worker 使用
- b、除非明确地更新缓存,否则缓存将不会被更新;除非删除,否则缓存数据不会过期
- c、因为每个浏览器都硬性限制了一个域下缓存数据的大小。缓存配额使用估算值,可以使用
StorageEstimateAPI 获得。浏览器尽其所能去管理磁盘空间,但它有可能删除一个域下的缓存数据。浏览器要么自动删除特定域的全部缓存,要么全部保留
2、谷歌缓存位置
缓存存储数据位置:
加载中使用缓存资源:
3、缓存方法
- 创建缓存对象:用于创建或访问缓存对象的方法是 caches.open() 。caches 是一个缓存存储对象的全局变量。open() 方法接受一个参数,即我们要访问的缓存对象的名称
caches.open("demo-cache").then((myCache) => {
// 在缓存对象 myCache 中进行操作
});
- 添加缓存:
//接受一个请求作为参数,请求可以是完整请求对象,也可以只是一个 UR
caches.open("demo-cache").then((myCache) => {
// 仅 URL
myCache.add("/subscribe");
// 完整的 Request 对象
myCache.add(new Request('/subscribe', {
method: "GET",
headers: new Headers({
'Content-Type': 'text/html'
}),
/* 其他 Request 配置 */
});
});
//添加多个请求,我们可以使用 addAll() 方法,该方法接受一组请求
caches.open("demo-cache").then((myCache) => {
myCache.addAll([
"/subscribe",
"/images/demo.png"
]);
});
- 获取缓存:
//在于特定的一个缓存对象中,指定缓存对象
caches.open("demo-cache").then((myCache) => {
myCache.match("/subscribe").then((cachedResponse) => {
if (cachedResponse) {
// 找到相关响应后操作
} else {
// 未找到相关响应后操作
}
});
});
//搜索与 URL 片段匹配的所有请求(例如 /images/ 路径中包含的所有请求),返回一个响应数组
caches.open("demo-cache").then((myCache) => {
myCache.matchAll("/images/").then((cachedResponses) => {
if (cachedResponses) {
// 找到相关响应后操作
} else {
// 未找到相关响应后操作
}
});
});
- 更新缓存:
//调用相同的 cache.add() 方法,执行请求页面的提取并替换相同 URL 的缓存中的响应
caches.open("demo-cache").then((myCache) => {
// 浏览器会重新请求并缓存响应
myCache.add("/subscribe");
});
//使用 cache.put() 方法,将请求/响应直接存储到缓存对象中
const request = new Request("/subscribe");
fetch(request).then((fetchResponse) => {
caches.open('demo-cache').then((myCache) => {
cache.put(request, fetchResponse);
});
});
- 删除缓存:
//删除特定对象的缓存
caches.open("demo-cache").then((myCache) => {
myCache.delete("/subscribe");
});
//删除缓存对象
caches.delete("demo-cache");
4、测试案例
//html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<iframe src="./web/index.html" frameborder="0" height="667px" width="375px"></iframe>
<img src="./2022-12-18-11-06-11.png" alt="" srcset="" style="width: 100px;height: 100px;">
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./demo-cache.js');
}
</script>
</body>
</html>
//demo-cache.js
var VERSION = 'v12';
// 缓存
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(VERSION).then(function (cache) {
//安装的时候,提前加载资源
return cache.addAll([
'./web/index.html',
'./2022-12-18-11-06-11.png',
'./cache.html'
]);
})
);
});
// 缓存更新
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames.map(function (cacheName) {
// 如果当前版本和缓存版本不一致
if (cacheName !== VERSION) {
return caches.delete(cacheName);
}
})
);
})
);
});
// 捕获请求并返回缓存数据
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).catch(function () {
return fetch(event.request);
}).then(function (response) {
if (response) {
caches.open(VERSION).then(function (cache) {
cache.put(event.request, response);
});
return response.clone();
}
return fetch(event.request).then(response => {
//资源不存在,重新加载且同时添加到缓存中
if (response) {
caches.open(VERSION).then(function (cache) {
cache.put(event.request, response);
});
return response.clone();
}
});
}).catch(function (error) {
// 处理 match() 或 fetch() 引起的异常。
console.error(' Error in fetch handler:', error);
throw error;
})
);
});
停用memoryCache、diskCache,且低网速3g条件下,结果发现资源全部被缓存了,第二次打开速度:
没被缓存下来,游戏资源加载的速度如图所示: