thien k phan
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.
notion image
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.
notion image
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!