Resource Hints Issues
What This Means
Resource hints are HTML elements that tell the browser to perform certain tasks early, before they're actually needed. When used correctly, they significantly improve page load performance. When misused, they waste bandwidth and can actually slow down your site.
Types of Resource Hints
dns-prefetch:
- Resolves domain name to IP address early
- Minimal overhead
- Use for third-party domains
preconnect:
- DNS resolution + TCP handshake + TLS negotiation
- More resource-intensive than dns-prefetch
- Use for critical third-party resources
preload:
- Fetches resource with high priority
- Resource will definitely be used on current page
- Most powerful but must use carefully
prefetch:
- Fetches resource with low priority
- For resources needed on next page navigation
- Doesn't block current page loading
modulepreload:
- Preloads JavaScript modules
- Specific to ES modules
- Handles dependencies automatically
Impact on Your Business
When Used Correctly:
- Faster page load times (100-300ms improvement)
- Better Core Web Vitals scores (FCP, LCP)
- Improved user experience
- Higher conversion rates
When Misconfigured:
- Wasted bandwidth from unused preloads
- Slower page loads from over-preloading
- Poor performance on slow connections
- Increased server load
Common Causes
Over-Preloading
<!-- Wrong: Too many preloads -->
<head>
<link rel="preload" href="/css/main.css" as="style">
<link rel="preload" href="/css/responsive.css" as="style">
<link rel="preload" href="/css/animations.css" as="style">
<link rel="preload" href="/css/print.css" as="style">
<link rel="preload" href="/js/app.js" as="script">
<link rel="preload" href="/js/analytics.js" as="script">
<link rel="preload" href="/js/chat.js" as="script">
<link rel="preload" href="/fonts/font1.woff2" as="font">
<link rel="preload" href="/fonts/font2.woff2" as="font">
<link rel="preload" href="/fonts/font3.woff2" as="font">
<!-- 10+ preloads can harm performance -->
</head>
Preloading Without Using
<!-- Wrong: Preloaded but never used -->
<link rel="preload" href="/unused-script.js" as="script">
<!-- Chrome warning: "resource was preloaded but not used" -->
Wrong Resource Type
<!-- Wrong: Incorrect 'as' attribute -->
<link rel="preload" href="/style.css" as="script">
<!-- Should be as="style" -->
<!-- Wrong: Missing 'as' attribute -->
<link rel="preload" href="/app.js">
<!-- Must specify as="script" -->
Missing Crossorigin for Fonts
<!-- Wrong: No crossorigin attribute -->
<link rel="preload" href="/fonts/font.woff2" as="font" type="font/woff2">
<!-- Correct: With crossorigin -->
<link rel="preload" href="/fonts/font.woff2" as="font" type="font/woff2" crossorigin>
Using Preload Instead of Prefetch
<!-- Wrong: High-priority preload for next-page resource -->
<link rel="preload" href="/next-page.html" as="document">
<!-- Correct: Low-priority prefetch -->
<link rel="prefetch" href="/next-page.html">
Too Many Preconnects
<!-- Wrong: Too many preconnects -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://analytics.google.com">
<link rel="preconnect" href="https://cdn.example.com">
<link rel="preconnect" href="https://api.example.com">
<link rel="preconnect" href="https://ads.example.com">
<!-- Limit to 3-4 critical third-party domains -->
How to Diagnose
Method 1: Chrome DevTools Console
- Open DevTools (
F12) - Go to Console tab
- Reload page
- Look for warnings
Common Warnings:
The resource <URL> was preloaded using link preload but not used within a few seconds from the window's load event.
A preload for '<URL>' is found, but is not used due to...
Method 2: Chrome DevTools Network Tab
- Open Network tab
- Enable "Priority" column (right-click headers)
- Reload page
- Check preloaded resources
What to Look For:
- Preloaded resources should have "Highest" or "High" priority
- Resources should be used (not just fetched)
- Timing: preloaded resources start early
- No duplicate requests for same resource
Method 3: Lighthouse Audit
- Open DevTools
- Go to Lighthouse tab
- Run Performance audit
- Check diagnostics:
Key Audits:
- "Preload key requests" - suggests resources to preload
- "Preconnect to required origins" - suggests preconnect opportunities
- "Unused JavaScript" - check if preloaded scripts are used
- "Largest Contentful Paint element" - consider preloading LCP resource
Method 4: PageSpeed Insights
- Visit PageSpeed Insights
- Enter your URL
- Review opportunities and diagnostics
What to Look For:
- "Preload key requests" opportunity
- Estimated time savings
- Specific resources to preload
- "Reduce unused JavaScript" warnings
Method 5: WebPageTest
- Visit WebPageTest.org
- Run test
- Check waterfall chart
- Look for:
- Early resource loading
- Connection timings
- Priority indicators
General Fixes
Fix 1: Preload Critical Resources Only
Limit preloads to 3-5 most critical resources:
<head>
<!-- 1. Critical CSS -->
<link rel="preload" href="/css/critical.css" as="style">
<!-- 2. Critical font (used above-fold) -->
<link rel="preload" href="/fonts/primary.woff2" as="font" type="font/woff2" crossorigin>
<!-- 3. LCP image (if not in HTML initially) -->
<link rel="preload" href="/images/hero.jpg" as="image">
<!-- 4. Critical JavaScript (if needed for interactivity) -->
<link rel="preload" href="/js/critical.js" as="script">
<!-- Then load them normally -->
<link rel="stylesheet" href="/css/critical.css">
<script src="/js/critical.js" defer></script>
</head>
Fix 2: Use Correct Resource Types
Match as attribute to resource type:
<!-- Stylesheets -->
<link rel="preload" href="/style.css" as="style">
<!-- Scripts -->
<link rel="preload" href="/app.js" as="script">
<!-- Fonts (requires crossorigin) -->
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
<!-- Images -->
<link rel="preload" href="/hero.jpg" as="image">
<!-- Video -->
<link rel="preload" href="/video.mp4" as="video">
<!-- Audio -->
<link rel="preload" href="/audio.mp3" as="audio">
<!-- Fetch (XHR/Fetch API requests) -->
<link rel="preload" href="/api/data.json" as="fetch" crossorigin>
<!-- Documents -->
<link rel="prefetch" href="/next-page.html" as="document">
Fix 3: Implement Preconnect for Third-Party Resources
Use preconnect for critical third-party domains:
<!-- Google Fonts (2 preconnects needed) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Analytics (if render-blocking) -->
<link rel="preconnect" href="https://www.google-analytics.com">
<!-- CDN for critical resources -->
<link rel="preconnect" href="https://cdn.example.com">
<!-- Limit to 3-4 most critical third-party domains -->
Fix 4: Use dns-prefetch for Non-Critical Third Parties
For non-critical third-party resources:
<!-- dns-prefetch: Lower overhead than preconnect -->
<link rel="dns-prefetch" href="https://analytics.google.com">
<link rel="dns-prefetch" href="https://ads.example.com">
<link rel="dns-prefetch" href="https://social-widgets.example.com">
<!-- Combine with preconnect fallback for older browsers -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
Fix 5: Implement Prefetch for Next Navigation
Prefetch resources for next page:
<!-- User likely to navigate to these pages -->
<link rel="prefetch" href="/products.html">
<link rel="prefetch" href="/checkout.html">
<!-- Prefetch critical resources for next page -->
<link rel="prefetch" href="/css/products.css">
<link rel="prefetch" href="/js/checkout.js">
<!-- Prefetch on user interaction -->
<script>
// Prefetch when user hovers over link
document.querySelectorAll('a[href="/products"]').forEach(link => {
link.addEventListener('mouseenter', () => {
const prefetchLink = document.createElement('link');
prefetchLink.rel = 'prefetch';
prefetchLink.href = '/products.html';
document.head.appendChild(prefetchLink);
}, { once: true });
});
</script>
Fix 6: Use Priority Hints with Preload
Combine preload with fetchpriority:
<!-- High priority: LCP image -->
<link rel="preload" href="/hero.jpg" as="image" fetchpriority="high">
<img src="/hero.jpg" fetchpriority="high" alt="Hero">
<!-- Low priority: Below-fold resources -->
<link rel="preload" href="/footer.js" as="script" fetchpriority="low">
<!-- Auto (default): Browser decides -->
<link rel="preload" href="/analytics.js" as="script" fetchpriority="auto">
Fix 7: Preload Responsive Images
Preload with responsive images:
<!-- Preload responsive image -->
<link rel="preload" as="image" href="/hero-mobile.jpg"
imagesrcset="/hero-mobile.jpg 400w,
/hero-tablet.jpg 800w,
/hero-desktop.jpg 1200w"
imagesizes="(max-width: 600px) 400px,
(max-width: 1000px) 800px,
1200px">
<!-- Then use in img tag -->
<img src="/hero-mobile.jpg"
srcset="/hero-mobile.jpg 400w,
/hero-tablet.jpg 800w,
/hero-desktop.jpg 1200w"
sizes="(max-width: 600px) 400px,
(max-width: 1000px) 800px,
1200px"
alt="Hero image">
Fix 8: Modulepreload for JavaScript Modules
For ES modules:
<!-- Preload main module and dependencies -->
<link rel="modulepreload" href="/js/app.js">
<link rel="modulepreload" href="/js/utils.js">
<link rel="modulepreload" href="/js/components.js">
<!-- Then load module -->
<script type="module" src="/js/app.js"></script>
Fix 9: Conditional Resource Hints
Load hints conditionally:
<script>
// Preload font only if not in cache
if (!document.fonts.check('1rem MyFont')) {
const preload = document.createElement('link');
preload.rel = 'preload';
preload.href = '/fonts/myfont.woff2';
preload.as = 'font';
preload.type = 'font/woff2';
preload.crossOrigin = 'anonymous';
document.head.appendChild(preload);
}
// Preconnect based on user's connection
if (navigator.connection && navigator.connection.effectiveType !== 'slow-2g') {
const link = document.createElement('link');
link.rel = 'preconnect';
link.href = 'https://cdn.example.com';
document.head.appendChild(link);
}
</script>
Platform-Specific Guides
Detailed implementation instructions for your specific platform:
| Platform | Troubleshooting Guide |
|---|---|
| WordPress | WordPress Resource Hints |
| Shopify | Shopify Preload Configuration |
| Wix | Wix Performance Settings |
| Squarespace | Squarespace Resource Hints |
| Webflow | Webflow Preload Setup |
| Custom HTML | HTML Resource Hints Guide |
Testing & Validation
After implementing resource hints:
Step 1: Check Console Warnings
- Open Chrome DevTools
- Go to Console tab
- Reload page
- Verify no "preload not used" warnings
- Fix any reported issues
Step 2: Verify Network Timing
- Open Network tab
- Enable "Priority" column
- Reload page
- Verify:
- Preloaded resources have high priority
- Resources load early
- No duplicate requests
- All preloaded resources are used
Step 3: Lighthouse Performance Audit
- Run Lighthouse audit
- Check Performance score
- Verify:
- "Preload key requests" passes or improves
- "Preconnect to required origins" passes
- No warnings about unused resources
Step 4: PageSpeed Insights
- Test on PageSpeed Insights
- Check for:
- Improved FCP and LCP scores
- "Preload key requests" not in opportunities
- Better overall performance score
Step 5: Real Device Testing
- Test on actual mobile device
- Use slow connection (3G)
- Verify:
- Page loads faster
- No bandwidth waste
- Critical resources load first
Step 6: Measure Impact
Compare before/after metrics:
// Measure preload impact
window.addEventListener('load', () => {
performance.getEntriesByType('resource').forEach(resource => {
if (resource.name.includes('preloaded-resource')) {
console.log('Preloaded resource timing:', {
name: resource.name,
startTime: resource.startTime,
duration: resource.duration,
transferSize: resource.transferSize
});
}
});
});
Common Mistakes
- Preloading too many resources - Limit to 3-5 critical resources
- Preloading without using - Every preload must be used on page
- Wrong as= attribute - Must match actual resource type
- Missing crossorigin for fonts - Required for CORS resources
- Using preload for next-page resources - Use prefetch instead
- Too many preconnects - Limit to 3-4 critical domains
- Not testing on slow connections - Over-preloading hurts slow connections
- Forgetting type for fonts - Should include type="font/woff2"
- Preloading third-party resources - May not work without CORS
- Not monitoring console warnings - Browser tells you about issues
Resource Hints Priority Guide
Use this guide to choose the right hint:
Use Preload When:
- Resource is critical for current page
- Resource will definitely be used
- You need high-priority loading
- Resource is same-origin or CORS-enabled
- Examples: Critical CSS, LCP image, critical fonts
Use Prefetch When:
- Resource is for next page navigation
- Low priority is acceptable
- Bandwidth is available after current page loads
- Examples: Next page HTML, next page images
Use Preconnect When:
- Third-party resource is critical
- You know domain in advance
- Limit to 3-4 most important domains
- Examples: Google Fonts, critical API, CDN
Use dns-prefetch When:
- Third-party resource is non-critical
- You want minimal overhead
- Fallback for preconnect
- Examples: Analytics, ads, social widgets