scratch-gui / src /playground /performance-sw.js
soiz1's picture
Upload folder using huggingface_hub
8fd7a1d verified
// MistWarp Performance Service Worker - Aggressive caching for 2x speedup
const CACHE_NAME = 'mistwarp-performance-v1';
const CACHE_URLS = [
// Critical block media
'/static/blocks-media/default/green-flag.svg',
'/static/blocks-media/default/stop.svg',
'/static/blocks-media/default/arrow.svg',
'/static/blocks-media/default/rotate-left.svg',
'/static/blocks-media/default/rotate-right.svg',
// Common assets
'/static/assets/scratch-cat.svg',
'/static/assets/pop.wav',
'/static/assets/meow.wav',
// Fonts
'https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap'
];
// Install event - preload critical resources
self.addEventListener('install', event => {
console.log('πŸš€ MistWarp Service Worker installing...');
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('πŸ“¦ Preloading critical resources');
return cache.addAll(CACHE_URLS);
})
.then(() => {
console.log('βœ… Service Worker installed and critical resources cached');
return self.skipWaiting();
})
.catch(error => {
console.error('❌ Service Worker install failed:', error);
})
);
});
// Activate event - clean up old caches
self.addEventListener('activate', event => {
console.log('πŸ”„ MistWarp Service Worker activating...');
event.waitUntil(
caches.keys()
.then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
console.log('πŸ—‘οΈ Deleting old cache:', cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log('βœ… Service Worker activated');
return self.clients.claim();
})
);
});
// Fetch event - cache strategy for performance
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// Only handle GET requests
if (event.request.method !== 'GET') {
return;
}
// Strategy: Cache First for static assets, Network First for everything else
if (shouldCacheResource(url)) {
event.respondWith(cacheFirstStrategy(event.request));
} else {
event.respondWith(networkFirstStrategy(event.request));
}
});
/**
* Determine if a resource should be cached
*/
function shouldCacheResource(url) {
const pathname = url.pathname;
// Cache static assets
return pathname.includes('/static/') ||
pathname.includes('/blocks-media/') ||
pathname.includes('/assets/') ||
pathname.endsWith('.svg') ||
pathname.endsWith('.png') ||
pathname.endsWith('.jpg') ||
pathname.endsWith('.wav') ||
pathname.endsWith('.mp3') ||
url.hostname === 'fonts.googleapis.com' ||
url.hostname === 'fonts.gstatic.com';
}
/**
* Cache First strategy - Check cache first, fallback to network
*/
async function cacheFirstStrategy(request) {
try {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.status === 200) {
const cache = await caches.open(CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.warn('Cache first strategy failed:', error);
return new Response('Network error', { status: 503 });
}
}
/**
* Network First strategy - Try network first, fallback to cache
*/
async function networkFirstStrategy(request) {
try {
const networkResponse = await fetch(request);
// Cache successful responses for future use
if (networkResponse.status === 200) {
const cache = await caches.open(CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
// Fallback to cache if network fails
const cachedResponse = await caches.match(request);
if (cachedResponse) {
return cachedResponse;
}
console.warn('Network first strategy failed, no cache available:', error);
return new Response('Network error', { status: 503 });
}
}