前沿技术/88.精读《Caches API》.md
caches 这个 API 是针对 Request Response 的。caches 一般结合 Service Worker 使用,因为请求级别的缓存与具有页面拦截功能的 Service Worker 最配。
本周精读的文章是 cache-api,介绍了浏览器缓存接口的基本语法。
浏览器拥有全局变量 caches 操作缓存。
caches 包含任意命名空间,可以通过 caches.open 创建或访问。
const myCache = await caches.open("myCache");
通过 add 添加缓存。由于 caches 缓存是基于请求的,因此参数可以是一个 URL 地址,或一个完整的 Request 对象:
// URL only
myCache.add("/subscribe");
// Full request object
myCache.add(new Request('/subscribe', {
method: "GET",
headers: new Headers({
'Content-Type': 'text/html'
}),
/* more request options */
});
每执行 add 时,浏览器都会主动请求并缓存返回的 Response。
可以通过 addAll 批量添加缓存:
myCache.addAll(["/subscribe", "/assets/images/profile.png"]);
通过 match 读取缓存。与 add 类似,参数可以是 URL 地址或完整 Request 对象,同时支持 matchAll:
const res = await myCache.match("/subscribe");
通过 add 或 put 更新缓存。
当某个请求缓存需要更新时,你可以重新执行 add 操作。
同时 put 也可以更新缓存,你可以手动构造返回值,这样浏览器就不需要发请求了:
const request = new Request("/subscribe");
const fetchResponse = await fetch(request);
myCache.put(request, fetchResponse);
通过 delete 销毁缓存。
你可以销毁某个路径的缓存:
myCache.delete("/subscribe");
也可以销毁某个缓存命名空间:
caches.delete("myCache");
可以利用 addEventListener('fetch') 监听浏览器请求时机,并在匹配到缓存时,直接替换为返回结果,当缓存不存在时才继续发请求。
self.addEventListener("fetch", (e) => {
e.respondWith(
// Check if item exists in cache
caches.match(e.request).then((cachedResponse) => {
// If found in cache, return cached response
if (cachedResponse) return cachedResponse;
// If not found, fetch over network
return fetch(e.request);
});
);
});
笔者利用 caches API + service worker 实现了纯浏览器端的后端渲染。
首先基于下面三个基本事实:
put 修改缓存。react-dom/server 可以在浏览器端执行。这三个能力组合一下,我们真的可以实现前端 SSR:
react-dom/server 构造一个 SSR 字符串。caches.put 添加当前页面缓存,将 react-root 部分塞入构造好的 SSR 字符串。前端渲染有几个好处:
笔者将这套前端渲染能力封装在 前端工程化工具 Pri 中,开启配置项
useServiceWorker=trueclientServerRender=true尝试。
后面有机会单独选一篇精读介绍 前端渲染,你也可以直接参考笔者 简陋的实现:由于 service worker 必须存在一个实体文件,因此脚手架会自动生成它,所以你看到的运行代码是一堆字符串。
前端渲染是一个较为极端的例子,caches 更多用来缓存简单的静态页面,静态博文,或者不经常变动的后端接口。
留下一个思考题:你还能想到 caches 的其他用法吗?欢迎留言。
如果你想参与讨论,请点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。