PageSourceSearch

https://snaggle.ai/static/js/progressive-loading.js

js snaggle.ai collected 2026-10-05 14:43:15 UTC 3,153 bytes, 88 lines download raw bytes

1// Progressive image loading implementation
2// Add service worker message listener for image loading
3if ('serviceWorker' in navigator) {
4    navigator.serviceWorker.addEventListener('message', event => {
5        if (event.data.type === 'IMAGE_LOADED') {
6            const images = document.querySelectorAll('.progressive-image');
7            images.forEach(img => {
8                if (img.dataset.src === event.data.url || 
9                    img.parentElement.querySelector('source')?.dataset.srcset === event.data.url) {
10                    img.src = img.dataset.src;
11                    img.classList.add('loaded');
12                }
13            });
14        }
15    });
16}
17
18document.addEventListener('DOMContentLoaded', async () => {
19    console.log('Checking for service worker...');
20    if ('serviceWorker' in navigator) {
21        navigator.serviceWorker.ready.then(registration => {
22            console.log('Service worker ready:', registration.active);
23        });
24    }
25
26    // Find all progressive images immediately
27    const images = document.querySelectorAll('.progressive-image');
28    
29    try {
30        const cache = await caches.open('snaggle-image-cache-v2');
31        
32        // Immediately start loading all images that are in cache
33        images.forEach(async img => {
34            const sources = img.parentElement.getElementsByTagName('source');
35            const webpSrc = sources[0]?.dataset.srcset;
36            
37            if (webpSrc) {
38                const cachedResponse = await cache.match(webpSrc);
39                if (cachedResponse) {
40                    sources[0].srcset = webpSrc;
41                    img.src = img.dataset.src;
42                    img.classList.add('loaded');
43                    return;
44                }
45                
46                // If not in cache, fetch it immediately
47                fetch(webpSrc).catch(console.error);
48            }
49        });
50    } catch (error) {
51        console.warn('Cache check failed:', error);
52    }
53    
54    // Keep intersection observer as fallback for uncached images
55    const imageObserver = new IntersectionObserver((entries, observer) => {
56        entries.forEach(entry => {
57            if (entry.isIntersecting) {
58                const img = entry.target;
59                const sources = img.parentElement.getElementsByTagName('source');
60                
61                // Load WebP source if available
62                Array.from(sources).forEach(source => {
63                    if (source.dataset.srcset) {
64                        source.srcset = source.dataset.srcset;
65                    }
66                });
67                
68                // Load main image
69                if (img.dataset.src) {
70                    img.src = img.dataset.src;
71                    img.classList.add('loaded');
72                }
73                
74                observer.unobserve(img);
75            }
76        });
77    }, {
78        rootMargin: '50px 0px',
79        threshold: 0.01
80    });
81
82    // Observe all images as fallback
83    images.forEach(img => {
84        if (!img.classList.contains('loaded')) {
85            imageObserver.observe(img);
86        }
87    });
88});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.