mirror of
https://github.com/dergigi/boris.git
synced 2025-12-17 06:34:24 +01:00
debug: add comprehensive logging for image caching
Add debug logs prefixed with [image-preload], [image-cache], [sw-image-cache], and [reader-header] to track: - When images are preloaded - Service Worker availability and controller status - Image fetch success/failure - Service Worker intercepting and caching image requests - Image loading in ReaderHeader component - Cache hits/misses in Service Worker This will help debug why images aren't available offline.
This commit is contained in:
@@ -37,6 +37,17 @@ const ReaderHeader: React.FC<ReaderHeaderProps> = ({
|
||||
onHighlightCountClick
|
||||
}) => {
|
||||
const cachedImage = useImageCache(image)
|
||||
|
||||
// Debug: Log image loading state
|
||||
React.useEffect(() => {
|
||||
if (image) {
|
||||
console.log('[reader-header] Image provided:', image)
|
||||
if (cachedImage) {
|
||||
console.log('[reader-header] Using cached image URL:', cachedImage)
|
||||
}
|
||||
}
|
||||
}, [image, cachedImage])
|
||||
|
||||
const { textColor } = useAdaptiveTextColor(cachedImage)
|
||||
const formattedDate = published ? format(new Date(published * 1000), 'MMM d, yyyy') : null
|
||||
const isLongSummary = summary && summary.length > 150
|
||||
@@ -80,7 +91,21 @@ const ReaderHeader: React.FC<ReaderHeaderProps> = ({
|
||||
<>
|
||||
<div className="reader-hero-image">
|
||||
{cachedImage ? (
|
||||
<img src={cachedImage} alt={title || 'Article image'} />
|
||||
<img
|
||||
src={cachedImage}
|
||||
alt={title || 'Article image'}
|
||||
onLoad={() => {
|
||||
console.log('[reader-header] ✅ Image loaded successfully:', cachedImage)
|
||||
}}
|
||||
onError={(e) => {
|
||||
console.error('[reader-header] ❌ Image failed to load:', cachedImage, {
|
||||
error: e,
|
||||
target: e.currentTarget,
|
||||
naturalWidth: e.currentTarget.naturalWidth,
|
||||
naturalHeight: e.currentTarget.naturalHeight
|
||||
})
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="reader-hero-placeholder">
|
||||
<FontAwesomeIcon icon={faNewspaper} />
|
||||
|
||||
@@ -12,6 +12,34 @@ export function useImageCache(
|
||||
// Service Worker handles everything - just return the URL as-is
|
||||
// The Service Worker will intercept fetch requests and cache them
|
||||
// Make sure images use standard <img src> tags for SW interception
|
||||
|
||||
// Debug: Log when image URL is provided
|
||||
if (imageUrl) {
|
||||
console.log('[image-cache] useImageCache hook called with URL:', imageUrl)
|
||||
|
||||
// Check if Service Worker is available
|
||||
if ('serviceWorker' in navigator) {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
console.log('[image-cache] ✅ Service Worker controller is active')
|
||||
} else {
|
||||
console.warn('[image-cache] ⚠️ Service Worker not controlling page - checking registration...')
|
||||
navigator.serviceWorker.getRegistration().then((reg) => {
|
||||
if (reg) {
|
||||
console.log('[image-cache] Service Worker registered but not controlling:', {
|
||||
active: !!reg.active,
|
||||
installing: !!reg.installing,
|
||||
waiting: !!reg.waiting
|
||||
})
|
||||
} else {
|
||||
console.warn('[image-cache] ❌ No Service Worker registration found')
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.warn('[image-cache] ❌ Service Workers not supported in this browser')
|
||||
}
|
||||
}
|
||||
|
||||
return imageUrl
|
||||
}
|
||||
|
||||
@@ -34,18 +62,49 @@ export function useCacheImageOnLoad(
|
||||
* images are cached before going offline
|
||||
*/
|
||||
export function preloadImage(imageUrl: string | undefined): void {
|
||||
if (!imageUrl) return
|
||||
if (!imageUrl) {
|
||||
console.log('[image-preload] Skipping - no image URL provided')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('[image-preload] Preloading image:', imageUrl)
|
||||
|
||||
// Check if Service Worker is available
|
||||
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
|
||||
console.log('[image-preload] ✅ Service Worker is active')
|
||||
} else {
|
||||
console.warn('[image-preload] ⚠️ Service Worker not active - images may not cache')
|
||||
}
|
||||
|
||||
// Create a link element with rel=prefetch or use Image object to trigger fetch
|
||||
// Service Worker will intercept and cache the request
|
||||
const img = new Image()
|
||||
|
||||
img.onload = () => {
|
||||
console.log('[image-preload] ✅ Image loaded successfully:', imageUrl)
|
||||
}
|
||||
|
||||
img.onerror = (err) => {
|
||||
console.error('[image-preload] ❌ Image failed to load:', imageUrl, err)
|
||||
}
|
||||
|
||||
img.src = imageUrl
|
||||
console.log('[image-preload] Created Image() object with src:', imageUrl)
|
||||
|
||||
// Also try using fetch to explicitly trigger Service Worker
|
||||
// This ensures the image is cached even if <img> tag hasn't rendered yet
|
||||
fetch(imageUrl, { mode: 'no-cors' }).catch(() => {
|
||||
// Ignore errors - image might not be CORS-enabled, but SW will still cache it
|
||||
// The Image() approach above will work for most cases
|
||||
})
|
||||
fetch(imageUrl, { mode: 'no-cors' })
|
||||
.then((response) => {
|
||||
console.log('[image-preload] ✅ Fetch successful for image:', imageUrl, {
|
||||
status: response.status,
|
||||
type: response.type,
|
||||
url: response.url
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.warn('[image-preload] ⚠️ Fetch failed (may be CORS issue, Image() should still work):', imageUrl, err)
|
||||
// Ignore errors - image might not be CORS-enabled, but SW will still cache it
|
||||
// The Image() approach above will work for most cases
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
32
src/sw.ts
32
src/sw.ts
@@ -31,6 +31,15 @@ registerRoute(
|
||||
/\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url.pathname)
|
||||
// Cache all images, not just cross-origin ones
|
||||
// This ensures article images from any source get cached
|
||||
|
||||
if (isImage) {
|
||||
console.log('[sw-image-cache] Intercepting image request:', {
|
||||
url: url.href,
|
||||
destination: request.destination,
|
||||
method: request.method
|
||||
})
|
||||
}
|
||||
|
||||
return isImage
|
||||
},
|
||||
new StaleWhileRevalidate({
|
||||
@@ -43,6 +52,29 @@ registerRoute(
|
||||
new CacheableResponsePlugin({
|
||||
statuses: [0, 200],
|
||||
}),
|
||||
{
|
||||
cacheKeyWillBeUsed: async ({ request }) => {
|
||||
console.log('[sw-image-cache] Cache key generated for:', request.url)
|
||||
return request
|
||||
},
|
||||
cacheWillUpdate: async ({ response }) => {
|
||||
console.log('[sw-image-cache] Caching response:', {
|
||||
url: response.url,
|
||||
status: response.status,
|
||||
type: response.type,
|
||||
ok: response.ok
|
||||
})
|
||||
return response.ok ? response : null
|
||||
},
|
||||
cachedResponseWillBeUsed: async ({ cachedResponse, request }) => {
|
||||
if (cachedResponse) {
|
||||
console.log('[sw-image-cache] ✅ Serving from cache:', request.url)
|
||||
} else {
|
||||
console.log('[sw-image-cache] ❌ No cached response found:', request.url)
|
||||
}
|
||||
return cachedResponse || null
|
||||
}
|
||||
}
|
||||
],
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user