Service Worker Caching
This is an archived post demonstrated a technique I used at Coc Coc to achieve offline mode for the new tab page
You should have used ServiceWorker or ApplicationCache to understand the article below:
- ServiceWorker - https://developers.google.com/web/fundamentals/primers/service-workers/
- ApplicationCache - https://developer.mozilla.org/enUS/docs/Web/HTML/Using_the_application_cache (No longer recommended on modern browsers version)
From mid-April to early June, I was tasked with implementing caching for the New Tab Mobile version on iOS and Android at Coc Coc. Although the workload was not too heavy, ensuring consistency across both operating systems was crucial for the New Tab Mobile version. The end result was a successful integration, with the application loading quickly and providing users with an offline experience when disconnected from the internet.
Recently, many developers have been using GatsbyJS, a static site generator that enables fast page loading through a combination of Service Worker and SSR. In production, ServiceWorker is installed and activated, while those new to Gatsby may not notice it on the development server.
To implement caching, I integrated ServiceWorker on Android and ApplicationCache on iOS. Here are some tips and successful caching strategies I implemented for Coc Coc New Tab for Mobile:
1. Both ServiceWorker and ApplicationCache enable offline page loading by caching assets programmatically.
2. To build caching options for Service Worker, SSL configuration is required. The use of a proxy like node-mitm-http-proxy can support SSL generation for convenience during development. Additionally, the web application must be served via HTTPS for both ServiceWorker and ApplicationCache caching options to work.
3. Under what conditions does the ServiceWorker decide to update the cache? For example, when you have built a new bundle and deployed it to production, create a
version
key in the application cache. The ServiceWorker mechanism will update when "a single byte changes in the fetched request." Don't let the ServiceWorker make the browser waste resources and bandwidth just to continuously fetch new requests. My recommendation is to create tempCache
and activeCache
; don't name the cache in a format like a date or commit hash. It will drive you crazy later when trying to maintain consistency.
A snippet I used in the project to move fetch requests into activeCache
, which the Service Worker will use to return responses from requests in the Application Cache:
/** * Copy tempCache to activeCache * @param {JSON} manifest - a list of URLs needing caching * @param {*} tempCache * @param {*} activeCache * @returns {Promise} */ async function copyCache( manifest, tempCache = 'tempCache', activeCache = 'activeCache' ) { // Delete the current activeCache in the application cache await caches.delete(activeCache).then(); // Open the fetched tempCache - prepare to copy to the new cache const tempCacheKeys = await (await caches.open(tempCache)).keys(); // Open the new activeCache const newCache = await caches.open(activeCache); // Add all tempCache requests to the new activeCache await Promise.all(tempCacheKeys.map(request => newCache.add(request))); await newCache.put( `https://version/!version_${manifest.version.replace(/\\//g, '_')}`, new Response('true') ); // Garbage Collector- remove tempCache - it's just a temp ;) await caches.delete(tempCache).then(); return newCache; } // Credit: Thien Phan
4. Since New Tab for Mobile can be considered a PWA, it is continuously updated through the version number in the
manifest.json
file of the ServiceWorker or manifest.appcache
of the ApplicationCache. Each time the page is refreshed on Android, the manifest.json
will be checked continuously for the presence of the version
key. The ServiceWorker will replace the entire old cache with the new cache. If not refreshed, within 24 hours, the ServiceWorker will automatically fetch manifest.json
to determine whether to replace the entire old cache or not. On iOS, using Application Cache requires users to manually refresh for the new cache to be updated, and the application updates to a new version.5. Apple only allows WebKit to use Service Worker. Other browsers, such as Chrome (not Safari), do not support ServiceWorker. That's why the New Tab Mobile version of the Coc Coc Browser on iOS has to use ApplicationCache as an alternative.
6. You should open
chrome:inspect
and select ServiceWorker to view the network and debug your ServiceWorker file.7. ApplicationCache requires you to define assets from the beginning in the fields ASSET, NETWORK, and FALLBACK in the
manifest.appcache
file within index.html
. This approach is quite static. However, with ServiceWorker, you have full control to programmatically decide which assets to cache.If you have any questions, feel free to contact me through the comments or via
thienphan@coccoc.com
!