diff --git a/package.json b/package.json index d0d9088..edc51a2 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "hexo-clean-css": "2.0.0", "hexo-uglify": "^2.0.0", "hexo-html-minifier": "^1.0.0", - "hexo-theme-amane": "0.0.34", + "hexo-theme-amane": "0.0.35", "hexo-theme-icarus": "5.2.1", "inferno": "^8.0.1", "inferno-create-element": "^8.0.1", diff --git a/scripts/service-worker-injector.js b/scripts/service-worker-injector.js new file mode 100644 index 0000000..ee22056 --- /dev/null +++ b/scripts/service-worker-injector.js @@ -0,0 +1 @@ +hexo.extend.injector.register('body_end', '', 'default'); diff --git a/source/js/sw.js b/source/js/sw.js new file mode 100644 index 0000000..5a76466 --- /dev/null +++ b/source/js/sw.js @@ -0,0 +1,262 @@ +importScripts('https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/workbox-sw.js'); + +workbox.setConfig({ + modulePathPrefix: 'https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/' +}); + +const { core, precaching, routing, strategies, expiration, cacheableResponse, backgroundSync } = workbox; +const { CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate } = strategies; +const { ExpirationPlugin } = expiration; +const { CacheableResponsePlugin } = cacheableResponse; + +const cacheSuffixVersion = '-231126', + // precacheCacheName = core.cacheNames.precache, + // runtimeCacheName = core.cacheNames.runtime, + maxEntries = 100; + +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((keys) => { + return Promise.all(keys.map((key) => { + if (key.includes('disqus-cdn-cache')) return caches.delete(key); + if (key.includes('disqus-img-cache')) return caches.delete(key); + if (!key.includes(cacheSuffixVersion)) return caches.delete(key); + })); + }) + ); +}); + + +core.setCacheNameDetails({ + prefix: 'amaneblog', + suffix: cacheSuffixVersion +}); + +core.skipWaiting(); +core.clientsClaim(); +precaching.cleanupOutdatedCaches(); + +routing.registerRoute( + /.*lf3-cdn-tos\.bytecdntp\.com/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +registerRoute( + /.*xgjalbum\.oss-cn-hangzhou\.aliyuncs\.com/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.staticfile\.org/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.nofated\.win/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*cdn\.jsdelivr\.net/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*fonts\.googleapis\.cn/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*fonts\.googleapis\.cn/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + +routing.registerRoute( + /.*fonts\.gstatic\.cn/, + new CacheFirst({ + cacheName: 'static-immutable' + cacheSuffixVersion, + fetchOptions: { + mode: 'cors', + credentials: 'omit' + }, + plugins: [ + new ExpirationPlugin({ + maxAgeSeconds: 30 * 24 * 60 * 60, + purgeOnQuotaError: true + }) + ] + }) +); + + +routing.registerRoute( + new RegExp('google-analytics.com'), + new NetworkOnly({ + plugins: [ + new backgroundSync.BackgroundSyncPlugin('ga', { + maxRetentionTime: 12 * 60 + }), + ] + }), + "POST" +); + +routing.registerRoute( + new RegExp('disqus'), + new NetworkFirst({ + plugins: [ + new backgroundSync.BackgroundSyncPlugin('disqus', { + maxRetentionTime: 12 * 60 + }), + ] + }) +); + +routing.registerRoute( + new RegExp('analytics.google.com'), + new NetworkOnly({ + plugins: [ + new backgroundSync.BackgroundSyncPlugin('ga_new', { + maxRetentionTime: 12 * 60 + }), + ] + }), + "POST" +) + +const StaleWhileRevalidateInstance = new StaleWhileRevalidate(); +/* + * Others img + * Method: staleWhileRevalidate + * cacheName: img-cache + */ +routing.registerRoute( + // Cache image files + /.*\.(?:png|jpg|jpeg|gif|webp)/, + StaleWhileRevalidateInstance +); + +/* + * Static Assets + * Method: staleWhileRevalidate + * cacheName: static-assets-cache + */ +routing.registerRoute( + // Cache CSS files + /.*\.(css|js)/, + // Use cache but update in the background ASAP + StaleWhileRevalidateInstance +); + +/* + * sw.js - Revalidate every time + * staleWhileRevalidate + */ +routing.registerRoute( + '/js/sw.js', + StaleWhileRevalidateInstance +); + + + +routing.registerRoute( + new RegExp('blog'), + StaleWhileRevalidateInstance +); + +routing.registerRoute( + /.*localhost/, + new NetworkOnly() +); + +/* + * Default - Serve as it is + * StaleWhileRevalidate + */ +routing.setDefaultHandler( + new NetworkOnly() +); \ No newline at end of file