[PWA] 17. Cache the photo
To cache photo, You need to spreate cache db to save the photo. So in wittr example, we cache the text already, if there in the wittr there is photo, we will create cache for it, so next time we can fetch from cache.
For the incoming photo, we also need to create cache for them.
For the 'install' event, we only cache assets, static imgs, css and js.
var staticCacheName = 'wittr-static-v7'; var contentImgsCache = 'wittr-content-imgs'; var allCaches = [ staticCacheName, contentImgsCache ]; self.addEventListener('install', function(event) { event.waitUntil( caches.open(staticCacheName).then(function(cache) { return cache.addAll([ '/skeleton', 'js/main.js', 'css/main.css', 'imgs/icon.png', 'https://fonts.gstatic.com/s/roboto/v15/2UX7WLTfW3W8TclTUvlFyQ.woff', 'https://fonts.gstatic.com/s/roboto/v15/d-6IYplOFocCacKzxwXSOD8E0i7KZn-EPnyo3HZu7kw.woff' ]); }) ); });
Here we don't cache dynamic photos. But at the beginning we define the cache name for photo .
self.addEventListener('activate', function(event) { event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.filter(function(cacheName) { return cacheName.startsWith('wittr-') && !allCaches.includes(cacheName); }).map(function(cacheName) { return caches.delete(cacheName); }) ); }) ); });
'activate' event is the place to clean the old version cahce but keep the current version cache and photo cache.
In 'fetch' event, this is the place we want to cache the photos.
For each request, we want to check,
- whether we have the cache for the photo request?
- if not, fetch from network and cache it.
self.addEventListener('fetch', function(event) { var requestUrl = new URL(event.request.url); // make sure the same origin if (requestUrl.origin === location.origin) { // serve cache with the skeleton if (requestUrl.pathname === '/') { event.respondWith(caches.match('/skeleton')); return; } // cache the photo if (requestUrl.pathname.startsWith('/photos/')) { event.respondWith(servePhoto(event.request)); return; } } // cache the assets event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); });
The servePhoto():
we want to make sure two things:
- we don't care the photo size, 800px,200px or 40px
- because respond object can be only access once, so we need clone() the original one and use clone one for the cahce, return the original one to the browser.
function servePhoto(request) { var storageUrl = request.url.replace(/-\d+px\.jpg$/, ''); return caches.open(contentImgsCache).then(function(cache) { return cache.match(storageUrl).then(function(response) { if (response) return response; return fetch(request).then(function(networkResponse) { cache.put(storageUrl, networkResponse.clone()); return networkResponse; }); }); }); }
So first, remove those px info: (/photos/awefaef-af23-fwq23f-800px.jpg) --> (/photos/awefaef-af23-fwq23f)
var storageUrl = request.url.replace(/-\d+px\.jpg$/, '');
Second, clone the network response and return origial one to browser and clone one to cache
return fetch(request).then(function(networkResponse) { cache.put(storageUrl, networkResponse.clone()); return networkResponse; });
Unitl now, we are able to cache the photo, event in the offline mode, we are still able to see the photos return from the cache.
相关文章
- HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 【异常】[ERROR] The cloud assistant is not installed on the ECS, or the cloud assistant is unavailable. cloudassistant is uninstall
- The total number of locks exceeds the lock table size错误(已纠正)
- Caused by: org.xml.sax.SAXParseException: The reference to entity "characterEncoding" must end with the ';' delimiter.
- Error: Connection lost: The server closed the connection
- [Tools] Kill the process running on port 8080
- [Git] Use and Compare the Different git Reset Options: --hard, --soft, and --mixed
- mysql启动时报错:Starting MySQL... ERROR! The server quit without updating PID file (/opt/mysql/data/mysql.pid) 的解决方法
- The response status was 0. Check out the W3C XMLHttpRequest Level 2 spec for
- 【Codeforces 1083A】The Fair Nut and the Best Path
- Fast enumeration variables cannot be modified in ARC by default; declare the variable __strong to al
- 已解决The above exception was the direct cause of the following exception:
- 已解决Resource stopwords not found. Please use the NLTK Downloader to obtain the resource:
- 什么是 Web3?解读未来的去中心化网络:The Decentralized Internet of the Future Explained
- 【成为架构师课程系列】使用 Cache-Aside 模式将数据存储在缓存中( Using the Cache-Aside pattern to store data in the cache)
- Java 虚拟机圖文詳解: JVM 體系結構 ( The JVM Architecture )
- macOS The bottle needs the Xcode CLT to be installed
- Warning:detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd".
- Sentinel采用SphO方式定义资源,报错:The order of entry exit can‘t be paired with the order of entry
- Kubernetes capacity planning: How to rightsize the requests of your cluster