Back to blog
PerformanceJanuary 1, 2024· 14 min read

Resource Hints and Preloading Strategies: Optimizing Web Performance

A practical Fusebox guide to resource hints and preloading strategies.

Resource Hints and Preloading Strategies: Optimizing Web Performance

Resource hints are powerful browser directives that help optimize loading performance by informing the browser about resources it will need in the near future. This guide explores how to detect, analyze, and implement resource hints for maximum performance gains.

Run This Resource Hint Analyzer Now

// Copy and paste this into your browser console to analyze resource loading strategies

class ResourceHintAnalyzer {
    constructor() {
        this.hints = {
            preconnect: [],
            prefetch: [],
            preload: [],
            prerender: [],
            dnsPrefetch: [],
            modulePreload: []
        };
        
        this.criticalResources = [];
        this.performance = window.performance;
        this.recommendations = [];
    }
    
    analyzeResourceHints() {
        console.log('=� Analyzing Resource Hints and Loading Strategies...\n');
        
        // Detect existing resource hints
        this.detectResourceHints();
        
        // Analyze resource timing
        this.analyzeResourceTiming();
        
        // Identify critical resources
        this.identifyCriticalResources();
        
        // Analyze third-party domains
        this.analyzeThirdPartyDomains();
        
        // Check for inefficient loading patterns
        this.detectInefficiencies();
        
        // Generate optimization report
        this.generateOptimizationReport();
    }
    
    detectResourceHints() {
        // Check link elements for resource hints
        const links = document.querySelectorAll('link');
        
        links.forEach(link => {
            const rel = link.rel.toLowerCase();
            const href = link.href;
            
            if (rel === 'preconnect') {
                this.hints.preconnect.push({
                    href,
                    crossorigin: link.crossOrigin
                });
            } else if (rel === 'prefetch') {
                this.hints.prefetch.push({
                    href,
                    as: link.as,
                    type: link.type
                });
            } else if (rel === 'preload') {
                this.hints.preload.push({
                    href,
                    as: link.as,
                    type: link.type,
                    crossorigin: link.crossOrigin,
                    media: link.media
                });
            } else if (rel === 'prerender') {
                this.hints.prerender.push({ href });
            } else if (rel === 'dns-prefetch') {
                this.hints.dnsPrefetch.push({ href });
            } else if (rel === 'modulepreload') {
                this.hints.modulePreload.push({ href });
            }
        });
        
        // Check for HTTP Link headers
        this.checkHTTPHeaders();
    }
    
    checkHTTPHeaders() {
        // Check the main document's headers
        const entries = this.performance.getEntriesByType('navigation');
        
        if (entries.length > 0) {
            console.log('9 Note: HTTP Link headers cannot be fully detected from JavaScript');
            console.log('   Check Network tab for Link headers in response');
        }
    }
    
    analyzeResourceTiming() {
        const resources = this.performance.getEntriesByType('resource');
        const timingAnalysis = {
            byType: {},
            slowResources: [],
            domains: new Map()
        };
        
        resources.forEach(resource => {
            const type = this.getResourceType(resource.name);
            const duration = resource.duration;
            const domain = new URL(resource.name).hostname;
            
            // Group by type
            if (!timingAnalysis.byType[type]) {
                timingAnalysis.byType[type] = {
                    count: 0,
                    totalDuration: 0,
                    resources: []
                };
            }
            
            timingAnalysis.byType[type].count++;
            timingAnalysis.byType[type].totalDuration += duration;
            timingAnalysis.byType[type].resources.push({
                url: resource.name,
                duration: Math.round(duration),
                size: resource.transferSize || 0
            });
            
            // Track slow resources
            if (duration > 500) {
                timingAnalysis.slowResources.push({
                    url: resource.name,
                    type,
                    duration: Math.round(duration),
                    startTime: Math.round(resource.startTime)
                });
            }
            
            // Track domains
            if (!timingAnalysis.domains.has(domain)) {
                timingAnalysis.domains.set(domain, {
                    count: 0,
                    totalDuration: 0,
                    hasPreconnect: this.hints.preconnect.some(h => h.href.includes(domain))
                });
            }
            
            const domainStats = timingAnalysis.domains.get(domain);
            domainStats.count++;
            domainStats.totalDuration += duration;
        });
        
        this.timingAnalysis = timingAnalysis;
    }
    
    getResourceType(url) {
        const extension = url.split('.').pop().split('?')[0].toLowerCase();
        
        const typeMap = {
            'js': 'JavaScript',
            'mjs': 'JavaScript',
            'css': 'CSS',
            'jpg': 'Image',
            'jpeg': 'Image',
            'png': 'Image',
            'gif': 'Image',
            'webp': 'Image',
            'svg': 'Image',
            'woff': 'Font',
            'woff2': 'Font',
            'ttf': 'Font',
            'otf': 'Font',
            'json': 'Data',
            'xml': 'Data'
        };
        
        return typeMap[extension] || 'Other';
    }
    
    identifyCriticalResources() {
        // Identify render-blocking resources
        const stylesheets = document.querySelectorAll('link[rel="stylesheet"]');
        const scripts = document.querySelectorAll('script[src]');
        
        stylesheets.forEach(stylesheet => {
            if (!stylesheet.media || stylesheet.media === 'all' || stylesheet.media === 'screen') {
                this.criticalResources.push({
                    type: 'CSS',
                    url: stylesheet.href,
                    renderBlocking: true,
                    preloaded: this.hints.preload.some(h => h.href === stylesheet.href)
                });
            }
        });
        
        scripts.forEach(script => {
            if (!script.async && !script.defer && script.src) {
                this.criticalResources.push({
                    type: 'JavaScript',
                    url: script.src,
                    renderBlocking: true,
                    preloaded: this.hints.preload.some(h => h.href === script.src)
                });
            }
        });
        
        // Check for critical fonts
        if (document.fonts) {
            document.fonts.forEach(font => {
                if (font.status === 'loaded') {
                    this.criticalResources.push({
                        type: 'Font',
                        family: font.family,
                        url: 'Unknown (check CSS)',
                        renderBlocking: false,
                        preloaded: false
                    });
                }
            });
        }
    }
    
    analyzeThirdPartyDomains() {
        const currentDomain = window.location.hostname;
        const thirdPartyDomains = new Map();
        
        this.timingAnalysis.domains.forEach((stats, domain) => {
            if (!domain.includes(currentDomain) && domain !== currentDomain) {
                thirdPartyDomains.set(domain, stats);
            }
        });
        
        // Check which third-party domains could benefit from preconnect
        thirdPartyDomains.forEach((stats, domain) => {
            if (!stats.hasPreconnect && stats.count >= 2) {
                this.recommendations.push({
                    type: 'preconnect',
                    domain,
                    reason: `${stats.count} resources loaded from this domain`,
                    impact: 'high'
                });
            }
        });
        
        this.thirdPartyDomains = thirdPartyDomains;
    }
    
    detectInefficiencies() {
        // Check for missing preload on critical resources
        this.criticalResources.forEach(resource => {
            if (resource.renderBlocking && !resource.preloaded) {
                this.recommendations.push({
                    type: 'preload',
                    resource: resource.url,
                    as: resource.type.toLowerCase(),
                    reason: 'Render-blocking resource not preloaded',
                    impact: 'high'
                });
            }
        });
        
        // Check for unnecessary preloads
        this.hints.preload.forEach(hint => {
            const isUsed = this.performance.getEntriesByName(hint.href).length > 0;
            
            if (!isUsed) {
                this.recommendations.push({
                    type: 'remove-preload',
                    resource: hint.href,
                    reason: 'Preloaded resource not used within 3 seconds',
                    impact: 'medium'
                });
            }
        });
        
        // Check for late-discovered resources
        const lateResources = this.timingAnalysis.slowResources.filter(r => r.startTime > 2000);
        
        lateResources.forEach(resource => {
            if (!this.hints.prefetch.some(h => h.href === resource.url)) {
                this.recommendations.push({
                    type: 'prefetch',
                    resource: resource.url,
                    reason: `Late discovery (started at ${resource.startTime}ms)`,
                    impact: 'medium'
                });
            }
        });
    }
    
    generateOptimizationReport() {
        console.log('=� Resource Hint Analysis Report\n');
        
        // Current hints summary
        console.log('=� Current Resource Hints:');
        Object.entries(this.hints).forEach(([type, hints]) => {
            if (hints.length > 0) {
                console.log(`\n${type}: ${hints.length} hints`);
                hints.slice(0, 3).forEach(hint => {
                    console.log(`  - ${hint.href || hint.family}`);
                });
                if (hints.length > 3) {
                    console.log(`  ... and ${hints.length - 3} more`);
                }
            }
        });
        
        // Resource timing summary
        console.log('\n� Resource Loading Performance:');
        Object.entries(this.timingAnalysis.byType).forEach(([type, stats]) => {
            const avgDuration = Math.round(stats.totalDuration / stats.count);
            console.log(`${type}: ${stats.count} resources, avg ${avgDuration}ms`);
        });
        
        // Critical resources
        if (this.criticalResources.length > 0) {
            console.log('\n=� Critical Resources:');
            this.criticalResources.forEach(resource => {
                const status = resource.preloaded ? ' Preloaded' : 'L Not preloaded';
                console.log(`  ${resource.type}: ${resource.url || resource.family} ${status}`);
            });
        }
        
        // Third-party domains
        if (this.thirdPartyDomains.size > 0) {
            console.log('\n< Third-party Domains:');
            this.thirdPartyDomains.forEach((stats, domain) => {
                const status = stats.hasPreconnect ? '' : 'L';
                console.log(`  ${domain}: ${stats.count} resources ${status}`);
            });
        }
        
        // Recommendations
        if (this.recommendations.length > 0) {
            console.log('\n=� Optimization Recommendations:');
            
            // Group by impact
            const highImpact = this.recommendations.filter(r => r.impact === 'high');
            const mediumImpact = this.recommendations.filter(r => r.impact === 'medium');
            
            if (highImpact.length > 0) {
                console.log('\nHigh Impact:');
                highImpact.forEach(rec => {
                    console.log(`  =4 ${rec.type}: ${rec.resource || rec.domain}`);
                    console.log(`     Reason: ${rec.reason}`);
                });
            }
            
            if (mediumImpact.length > 0) {
                console.log('\nMedium Impact:');
                mediumImpact.forEach(rec => {
                    console.log(`  =� ${rec.type}: ${rec.resource || rec.domain}`);
                    console.log(`     Reason: ${rec.reason}`);
                });
            }
        }
        
        // Generate implementation code
        this.generateImplementationCode();
    }
    
    generateImplementationCode() {
        console.log('\n=� Implementation Code:\n');
        
        const highImpactRecs = this.recommendations.filter(r => r.impact === 'high');
        
        if (highImpactRecs.length > 0) {
            console.log('<!-- Add to <head> section -->');
            
            highImpactRecs.forEach(rec => {
                if (rec.type === 'preconnect') {
                    console.log(`<link rel="preconnect" href="https://${rec.domain}" crossorigin>`);
                } else if (rec.type === 'preload') {
                    const crossorigin = rec.resource.includes(window.location.hostname) ? '' : ' crossorigin';
                    console.log(`<link rel="preload" href="${rec.resource}" as="${rec.as}"${crossorigin}>`);
                }
            });
        }
    }
}

// Run the analyzer
const analyzer = new ResourceHintAnalyzer();
analyzer.analyzeResourceHints();

Understanding Resource Hints

1. DNS Prefetch

Resolves domain names before resources are requested:

<link rel="dns-prefetch" href="//example.com">

2. Preconnect

Establishes early connections (DNS + TCP + TLS):

<link rel="preconnect" href="https://example.com" crossorigin>

3. Prefetch

Downloads resources for likely future navigation:

<link rel="prefetch" href="/next-page.js" as="script">

4. Preload

Downloads critical resources for current navigation:

<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>

5. Prerender (Deprecated)

Pre-renders entire pages (use with caution):

<link rel="prerender" href="/next-page.html">

Advanced Resource Loading Optimizer

// Copy and paste this comprehensive resource optimizer

class ResourceLoadingOptimizer {
    constructor() {
        this.criticalCSS = new Set();
        this.criticalFonts = new Set();
        this.lazyImages = [];
        this.asyncScripts = [];
        this.config = {
            lazyLoadOffset: 50,
            preloadLimit: 5,
            prefetchAfterLoad: true
        };
    }
    
    optimizeResourceLoading() {
        console.log('=' Optimizing Resource Loading...\n');
        
        // Extract and inline critical CSS
        this.extractCriticalCSS();
        
        // Optimize font loading
        this.optimizeFontLoading();
        
        // Implement lazy loading for images
        this.setupLazyLoading();
        
        // Optimize script loading
        this.optimizeScriptLoading();
        
        // Setup prefetching strategy
        this.setupPrefetchingStrategy();
        
        // Monitor and adapt
        this.setupPerformanceMonitoring();
    }
    
    extractCriticalCSS() {
        const stylesheets = document.querySelectorAll('link[rel="stylesheet"]');
        const criticalSelectors = new Set();
        
        // Identify above-the-fold elements
        const viewportHeight = window.innerHeight;
        const elements = document.querySelectorAll('*');
        
        elements.forEach(element => {
            const rect = element.getBoundingClientRect();
            if (rect.top < viewportHeight && rect.bottom > 0) {
                // Element is in viewport
                criticalSelectors.add(element.tagName.toLowerCase());
                
                if (element.id) {
                    criticalSelectors.add(`#${element.id}`);
                }
                
                if (element.className) {
                    element.classList.forEach(cls => {
                        criticalSelectors.add(`.${cls}`);
                    });
                }
            }
        });
        
        console.log(`=� Found ${criticalSelectors.size} critical selectors`);
        
        // Generate critical CSS recommendation
        this.generateCriticalCSSRecommendation(criticalSelectors);
    }
    
    generateCriticalCSSRecommendation(selectors) {
        console.log('\n=� Critical CSS Strategy:');
        console.log('1. Extract styles for these selectors:', 
                    Array.from(selectors).slice(0, 10).join(', '), '...');
        console.log('2. Inline critical CSS in <head>');
        console.log('3. Load full CSS asynchronously:');
        console.log(`
<link rel="preload" href="style.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>
        `.trim());
    }
    
    optimizeFontLoading() {
        // Detect font usage
        const fontPromises = [];
        
        if (document.fonts) {
            document.fonts.forEach(font => {
                if (font.status === 'loading' || font.status === 'loaded') {
                    this.criticalFonts.add({
                        family: font.family,
                        weight: font.weight,
                        style: font.style,
                        status: font.status
                    });
                }
            });
        }
        
        // Check computed styles for font usage
        const elementsToCheck = document.querySelectorAll('h1, h2, h3, h4, h5, h6, p, a, button');
        const usedFonts = new Set();
        
        elementsToCheck.forEach(element => {
            const style = window.getComputedStyle(element);
            const fontFamily = style.fontFamily;
            
            if (fontFamily && !fontFamily.includes('serif') && !fontFamily.includes('sans-serif')) {
                usedFonts.add(fontFamily.replace(/['"]/g, ''));
            }
        });
        
        console.log('\n=$ Font Optimization:');
        console.log(`Detected ${usedFonts.size} custom fonts`);
        
        // Generate font loading strategy
        this.generateFontStrategy(usedFonts);
    }
    
    generateFontStrategy(fonts) {
        console.log('\n=� Optimal Font Loading:');
        console.log('```html');
        fonts.forEach(font => {
            console.log(`<link rel="preload" href="/fonts/${font}.woff2" as="font" type="font/woff2" crossorigin>`);
        });
        console.log('```');
        
        console.log('\nCSS Font Loading API:');
        console.log('```javascript');
        console.log(`
const fontPromises = [
    document.fonts.load('1rem ${Array.from(fonts)[0]}'),
    // Add more fonts
];

Promise.all(fontPromises).then(() => {
    document.body.classList.add('fonts-loaded');
});
        `.trim());
        console.log('```');
    }
    
    setupLazyLoading() {
        const images = document.querySelectorAll('img[src]');
        const iframes = document.querySelectorAll('iframe[src]');
        
        // Identify images below the fold
        const viewportHeight = window.innerHeight;
        
        images.forEach(img => {
            const rect = img.getBoundingClientRect();
            
            if (rect.top > viewportHeight + this.config.lazyLoadOffset) {
                this.lazyImages.push({
                    element: img,
                    src: img.src,
                    position: rect.top,
                    isLazy: img.loading === 'lazy'
                });
            }
        });
        
        console.log(`\n=� Lazy Loading Analysis:`);
        console.log(`Total images: ${images.length}`);
        console.log(`Below fold: ${this.lazyImages.length}`);
        console.log(`Already lazy: ${this.lazyImages.filter(i => i.isLazy).length}`);
        
        // Generate lazy loading implementation
        this.generateLazyLoadingCode();
    }
    
    generateLazyLoadingCode() {
        console.log('\n=� Lazy Loading Implementation:');
        
        // Native lazy loading
        console.log('\n1. Native Lazy Loading (Modern Browsers):');
        console.log('```html');
        console.log('<img src="image.jpg" loading="lazy" alt="Description">');
        console.log('```');
        
        // Intersection Observer approach
        console.log('\n2. Intersection Observer (Better Control):');
        console.log('```javascript');
        console.log(`
const lazyImageObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src;
            img.classList.remove('lazy');
            lazyImageObserver.unobserve(img);
        }
    });
}, {
    rootMargin: '50px 0px',
    threshold: 0.01
});

document.querySelectorAll('img.lazy').forEach(img => {
    lazyImageObserver.observe(img);
});
        `.trim());
        console.log('```');
    }
    
    optimizeScriptLoading() {
        const scripts = document.querySelectorAll('script[src]');
        const scriptAnalysis = {
            blocking: [],
            async: [],
            defer: [],
            module: []
        };
        
        scripts.forEach(script => {
            const scriptInfo = {
                src: script.src,
                size: 'Unknown',
                position: script.parentElement.tagName
            };
            
            if (script.type === 'module') {
                scriptAnalysis.module.push(scriptInfo);
            } else if (script.async) {
                scriptAnalysis.async.push(scriptInfo);
            } else if (script.defer) {
                scriptAnalysis.defer.push(scriptInfo);
            } else {
                scriptAnalysis.blocking.push(scriptInfo);
            }
        });
        
        console.log('\n=� Script Loading Analysis:');
        console.log(`Blocking: ${scriptAnalysis.blocking.length}`);
        console.log(`Async: ${scriptAnalysis.async.length}`);
        console.log(`Defer: ${scriptAnalysis.defer.length}`);
        console.log(`Module: ${scriptAnalysis.module.length}`);
        
        // Generate recommendations
        if (scriptAnalysis.blocking.length > 0) {
            console.log('\n� Blocking Scripts Found:');
            scriptAnalysis.blocking.forEach(script => {
                console.log(`  - ${script.src}`);
                console.log(`    Consider adding async or defer attribute`);
            });
        }
    }
    
    setupPrefetchingStrategy() {
        console.log('\n=. Prefetching Strategy:\n');
        
        // Analyze navigation patterns
        const links = document.querySelectorAll('a[href]');
        const internalLinks = Array.from(links).filter(link => {
            try {
                const url = new URL(link.href);
                return url.hostname === window.location.hostname;
            } catch {
                return false;
            }
        });
        
        // Identify high-priority prefetch candidates
        const navigationLinks = internalLinks.filter(link => {
            // Main navigation links
            return link.closest('nav') || link.closest('header');
        });
        
        console.log(`Found ${navigationLinks.length} navigation links for prefetching`);
        
        // Generate prefetch implementation
        this.generatePrefetchStrategy(navigationLinks);
    }
    
    generatePrefetchStrategy(links) {
        console.log('\n=� Intelligent Prefetching:');
        console.log('```javascript');
        console.log(`
// Prefetch on hover with delay
const prefetchedUrls = new Set();

function prefetchUrl(url) {
    if (!prefetchedUrls.has(url)) {
        const link = document.createElement('link');
        link.rel = 'prefetch';
        link.href = url;
        document.head.appendChild(link);
        prefetchedUrls.add(url);
    }
}

// Setup hover prefetching
document.querySelectorAll('a[href]').forEach(link => {
    let timer;
    
    link.addEventListener('mouseenter', () => {
        timer = setTimeout(() => {
            const url = link.href;
            if (url.startsWith(window.location.origin)) {
                prefetchUrl(url);
            }
        }, 200); // 200ms delay
    });
    
    link.addEventListener('mouseleave', () => {
        clearTimeout(timer);
    });
});

// Prefetch visible links in viewport
const linkObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            const url = entry.target.href;
            if (url.startsWith(window.location.origin)) {
                prefetchUrl(url);
            }
        }
    });
}, {
    rootMargin: '0px 0px 50px 0px'
});

document.querySelectorAll('a[href]').forEach(link => {
    linkObserver.observe(link);
});
        `.trim());
        console.log('```');
    }
    
    setupPerformanceMonitoring() {
        console.log('\n=� Performance Monitoring Setup:');
        console.log('```javascript');
        console.log(`
// Monitor resource timing
const perfObserver = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (entry.duration > 1000) {
            console.warn('Slow resource:', entry.name, entry.duration + 'ms');
            
            // Consider prefetching similar resources
            if (entry.initiatorType === 'script' || entry.initiatorType === 'css') {
                // Add to prefetch queue for next navigation
                localStorage.setItem('prefetch-' + entry.name, 'true');
            }
        }
    }
});

perfObserver.observe({ entryTypes: ['resource'] });

// Adaptive loading based on connection
if ('connection' in navigator) {
    const connection = navigator.connection;
    
    if (connection.effectiveType === '4g') {
        // Aggressive prefetching
        console.log('Fast connection detected - enabling aggressive prefetching');
    } else if (connection.effectiveType === '3g' || connection.effectiveType === '2g') {
        // Conservative loading
        console.log('Slow connection detected - disabling prefetching');
    }
    
    // Monitor connection changes
    connection.addEventListener('change', () => {
        console.log('Connection changed to:', connection.effectiveType);
    });
}
        `.trim());
        console.log('```');
    }
}

// Run the optimizer
const optimizer = new ResourceLoadingOptimizer();
optimizer.optimizeResourceLoading();

Resource Priority Hints

Priority Hints API

Control fetch priority for resources:

// High priority for critical resources
<img src="hero.jpg" fetchpriority="high">
<link rel="stylesheet" href="critical.css" fetchpriority="high">

// Low priority for below-the-fold content
<img src="footer-logo.jpg" fetchpriority="low">
<script src="analytics.js" fetchpriority="low"></script>

// Auto priority (default)
<img src="content.jpg" fetchpriority="auto">

Common Resource Loading Patterns

1. Critical Path Optimization

// Identify and optimize critical rendering path
const criticalPathAnalyzer = () => {
    const critical = {
        css: [],
        js: [],
        fonts: []
    };
    
    // Find render-blocking CSS
    document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
        if (!link.media || link.media === 'all') {
            critical.css.push(link.href);
        }
    });
    
    // Find render-blocking JavaScript
    document.querySelectorAll('script:not([async]):not([defer])').forEach(script => {
        if (script.src) {
            critical.js.push(script.src);
        }
    });
    
    console.log('Critical Resources:', critical);
    
    // Generate optimization strategy
    return {
        inline: critical.css.length > 3,
        preload: critical.css.concat(critical.js),
        defer: true
    };
};

2. Progressive Enhancement Loading

// Load enhancements based on device capabilities
const progressiveLoader = () => {
    const enhancements = [];
    
    // Check for high-end device features
    if (window.matchMedia('(min-width: 1200px)').matches) {
        enhancements.push('/js/desktop-enhancements.js');
    }
    
    // Check for touch support
    if ('ontouchstart' in window) {
        enhancements.push('/js/touch-gestures.js');
    }
    
    // Check for WebGL support
    if (window.WebGLRenderingContext) {
        enhancements.push('/js/3d-graphics.js');
    }
    
    // Load enhancements
    enhancements.forEach(src => {
        const script = document.createElement('script');
        script.src = src;
        script.async = true;
        document.body.appendChild(script);
    });
};

3. Service Worker Prefetching

// Advanced prefetching with Service Worker
if ('serviceWorker' in navigator) {
    // Register service worker
    navigator.serviceWorker.register('/sw.js');
    
    // Service worker code (sw.js)
    const PREFETCH_CACHE = 'prefetch-v1';
    const urlsToPrefetch = [
        '/next-page.html',
        '/styles/next-page.css',
        '/scripts/next-page.js'
    ];
    
    self.addEventListener('install', event => {
        event.waitUntil(
            caches.open(PREFETCH_CACHE)
                .then(cache => cache.addAll(urlsToPrefetch))
        );
    });
}

Performance Budget Implementation

// Monitor and enforce performance budgets
class PerformanceBudgetMonitor {
    constructor(budgets) {
        this.budgets = budgets || {
            js: 300 * 1024,        // 300KB
            css: 100 * 1024,       // 100KB
            images: 1000 * 1024,   // 1MB
            fonts: 200 * 1024,     // 200KB
            total: 2000 * 1024     // 2MB
        };
        
        this.violations = [];
    }
    
    checkBudgets() {
        const resources = performance.getEntriesByType('resource');
        const usage = {
            js: 0,
            css: 0,
            images: 0,
            fonts: 0,
            total: 0
        };
        
        resources.forEach(resource => {
            const size = resource.transferSize || 0;
            const type = this.getResourceCategory(resource.name);
            
            if (usage[type] !== undefined) {
                usage[type] += size;
            }
            usage.total += size;
        });
        
        // Check for violations
        Object.entries(this.budgets).forEach(([type, budget]) => {
            if (usage[type] > budget) {
                this.violations.push({
                    type,
                    usage: usage[type],
                    budget: budget,
                    overBy: ((usage[type] - budget) / 1024).toFixed(1) + 'KB'
                });
            }
        });
        
        this.generateBudgetReport(usage);
    }
    
    getResourceCategory(url) {
        if (/\.js(\?|$)/.test(url)) return 'js';
        if (/\.css(\?|$)/.test(url)) return 'css';
        if (/\.(jpg|jpeg|png|gif|webp|svg)(\?|$)/.test(url)) return 'images';
        if (/\.(woff|woff2|ttf|otf)(\?|$)/.test(url)) return 'fonts';
        return 'other';
    }
    
    generateBudgetReport(usage) {
        console.log('\n=� Performance Budget Report:\n');
        
        Object.entries(usage).forEach(([type, bytes]) => {
            const budget = this.budgets[type];
            const percentage = ((bytes / budget) * 100).toFixed(1);
            const status = bytes > budget ? 'L' : '';
            
            console.log(`${type}: ${(bytes / 1024).toFixed(1)}KB / ${(budget / 1024).toFixed(0)}KB (${percentage}%) ${status}`);
        });
        
        if (this.violations.length > 0) {
            console.log('\n� Budget Violations:');
            this.violations.forEach(violation => {
                console.log(`  ${violation.type}: Over by ${violation.overBy}`);
            });
        }
    }
}

// Check performance budgets
const budgetMonitor = new PerformanceBudgetMonitor();
budgetMonitor.checkBudgets();

Real-World Performance Wins

1. Amazon (2019)

Implemented aggressive prefetching, reducing page load time by 1.2 seconds and increasing conversions by 2%.

2. Netflix (2020)

Used predictive prefetching based on user behavior, reducing time-to-play by 50%.

3. Instagram (2021)

Implemented route-based code splitting with prefetching, improving interaction time by 23%.

Implementation Best Practices

Resource Hint Strategy

<!-- Optimal order in <head> -->
<!DOCTYPE html>
<html>
<head>
    <!-- 1. Preconnect to critical third-party origins -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://cdn.example.com" crossorigin>
    
    <!-- 2. DNS prefetch for other third-parties -->
    <link rel="dns-prefetch" href="//www.google-analytics.com">
    
    <!-- 3. Preload critical resources -->
    <link rel="preload" href="/css/critical.css" as="style">
    <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
    
    <!-- 4. Prefetch next-page resources -->
    <link rel="prefetch" href="/next-page.js">
    
    <!-- 5. Actual resource loading -->
    <link rel="stylesheet" href="/css/critical.css">
</head>

Adaptive Loading Strategy

// Adapt resource loading based on user context
const adaptiveLoader = {
    init() {
        this.connectionType = this.getConnectionType();
        this.deviceMemory = navigator.deviceMemory || 4;
        this.saveData = navigator.connection?.saveData || false;
        
        this.loadResources();
    },
    
    getConnectionType() {
        if (!navigator.connection) return '4g';
        return navigator.connection.effectiveType;
    },
    
    loadResources() {
        if (this.saveData) {
            console.log('Save-Data mode: Loading minimal resources');
            return;
        }
        
        switch (this.connectionType) {
            case '4g':
                this.loadHighQuality();
                this.enablePrefetching();
                break;
            case '3g':
                this.loadMediumQuality();
                this.enableSelectivePrefetching();
                break;
            case '2g':
            case 'slow-2g':
                this.loadLowQuality();
                this.disablePrefetching();
                break;
        }
    },
    
    loadHighQuality() {
        // Load high-res images, videos, etc.
        document.querySelectorAll('[data-src-high]').forEach(el => {
            el.src = el.dataset.srcHigh;
        });
    },
    
    enablePrefetching() {
        // Enable aggressive prefetching
        document.querySelectorAll('a[href]').forEach(link => {
            if (link.href.startsWith(window.location.origin)) {
                const prefetchLink = document.createElement('link');
                prefetchLink.rel = 'prefetch';
                prefetchLink.href = link.href;
                document.head.appendChild(prefetchLink);
            }
        });
    }
};

Conclusion

Resource hints and preloading strategies are powerful tools for optimizing web performance. By understanding when and how to use each hint type, you can significantly improve loading times and user experience. Remember to measure the impact of your optimizations and adapt your strategy based on real user metrics and network conditions.

The key is finding the right balance between aggressive optimization and bandwidth consideration, always keeping your users' context and capabilities in mind.