Skip to content

Commit dd49288

Browse files
authored
Create sw.js
1 parent 77f8d80 commit dd49288

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

sw.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const CACHE_NAME = 'mr-core-cache-v3';
2+
const OFFLINE_URL = '/offline.html';
3+
4+
/**
5+
* 1. PRECACHE CORE ASSETS
6+
* These files are downloaded immediately when the user visits the site.
7+
* This ensures your Offline Page looks beautiful (has fonts & logos) even without internet.
8+
*/
9+
const CORE_ASSETS = [
10+
OFFLINE_URL,
11+
'/manifest.webmanifest',
12+
'/src/CoreSans-Regular_en.otf',
13+
'/src/mrc-nuca.svg'
14+
];
15+
16+
/**
17+
* 2. INSTALL EVENT
18+
* Triggered when the service worker is first registered.
19+
*/
20+
self.addEventListener('install', event => {
21+
self.skipWaiting(); // Forces the waiting service worker to become the active service worker
22+
event.waitUntil(
23+
caches.open(CACHE_NAME).then(cache => {
24+
console.log('[SW] Precaching Core Assets');
25+
return cache.addAll(CORE_ASSETS);
26+
})
27+
);
28+
});
29+
30+
/**
31+
* 3. ACTIVATE EVENT
32+
* Triggered when the service worker takes control. Great for cleaning up old caches.
33+
*/
34+
self.addEventListener('activate', event => {
35+
event.waitUntil(
36+
caches.keys().then(cacheNames => {
37+
return Promise.all(
38+
cacheNames.map(cache => {
39+
if (cache !== CACHE_NAME) {
40+
console.log('[SW] Clearing old cache:', cache);
41+
return caches.delete(cache);
42+
}
43+
})
44+
);
45+
}).then(() => self.clients.claim())
46+
);
47+
});
48+
49+
/**
50+
* 4. FETCH EVENT (THE BOOSTED ROUTER)
51+
* Intercepts all network requests and applies performance strategies.
52+
*/
53+
self.addEventListener('fetch', event => {
54+
const request = event.request;
55+
56+
// Ignore non-GET requests (like form submissions)
57+
if (request.method !== 'GET') return;
58+
59+
// ====================================================================
60+
// STRATEGY 1: HTML PAGES (Network First, Fallback to Cache, Fallback to Offline)
61+
// ====================================================================
62+
if (request.mode === 'navigate' || request.headers.get('accept').includes('text/html')) {
63+
event.respondWith(
64+
fetch(request)
65+
.then(response => {
66+
// If online, save a copy of this page to the cache for future offline visits
67+
const clone = response.clone();
68+
caches.open(CACHE_NAME).then(cache => cache.put(request, clone));
69+
return response;
70+
})
71+
.catch(async () => {
72+
// If offline, check if we have visited this page before
73+
const cachedResponse = await caches.match(request);
74+
if (cachedResponse) return cachedResponse;
75+
76+
// If offline and never visited this page, serve the custom offline.html
77+
return caches.match(OFFLINE_URL);
78+
})
79+
);
80+
return;
81+
}
82+
83+
// ====================================================================
84+
// STRATEGY 2: STATIC ASSETS (Stale-While-Revalidate)
85+
// Fonts, Images, CSS, JS
86+
// ====================================================================
87+
if (['font', 'image', 'style', 'script'].includes(request.destination)) {
88+
event.respondWith(
89+
caches.match(request).then(cachedResponse => {
90+
// Fetch fresh asset from network in the background
91+
const fetchPromise = fetch(request).then(networkResponse => {
92+
caches.open(CACHE_NAME).then(cache => {
93+
cache.put(request, networkResponse.clone());
94+
});
95+
return networkResponse;
96+
}).catch(() => null); // Silently fail if offline
97+
98+
// Return cached asset IMMEDIATELY (blazing fast), or wait for network if not cached
99+
return cachedResponse || fetchPromise;
100+
})
101+
);
102+
return;
103+
}
104+
});

0 commit comments

Comments
 (0)