Lazy Loading Pitfalls: When NOT to Lazy Load Images
Lazy Loading Pitfalls: When NOT to Lazy Load Images
Lazy loading images is widely recommended for performance—but applied blindly,
it can actually make your site slower, hurt Core Web Vitals, and break user experience.
This article explains when you should NOT lazy load images in WordPress themes,
why it happens, and how to control lazy loading safely at the code level.
Why Lazy Loading Exists (And Its Limits)
Native lazy loading (loading="lazy") tells the browser:
- Delay loading this image until it’s near the viewport
- Reduce initial network requests
- Improve perceived speed on long pages
This works well for below-the-fold content.
But above-the-fold images follow very different performance rules.
Pitfall 1: Lazy Loading the LCP Image (Most Common Mistake)
Your Largest Contentful Paint (LCP) element is often:
- Hero image
- Featured image
- First large thumbnail in an archive
If that image is lazy loaded, the browser intentionally delays it.
This directly increases LCP time.
Bad (Default Behavior in Many Themes)
<img src="hero.jpg" loading="lazy" alt="">
Correct: Force Eager Loading for the LCP Image
<?php
echo wp_get_attachment_image(
get_post_thumbnail_id(),
'large',
false,
array(
'loading' => 'eager',
'fetchpriority' => 'high',
)
);
?>
Only one image per page should get this treatment.
Pitfall 2: Lazy Loading Images That Are Immediately Visible
Images that are visible on first paint should not be lazy loaded:
- Above-the-fold thumbnails
- Logos in the header
- Hero background images
- First card in a listing
Lazy loading introduces:
- Extra delay before request starts
- Layout instability if dimensions are wrong
- Flicker during fast scrolling
Header Logo Example
<?php
// Header logo should be eager
echo wp_get_attachment_image(
get_theme_mod( 'custom_logo' ),
'full',
false,
array(
'loading' => 'eager',
'decoding' => 'async',
)
);
?>
Pitfall 3: Lazy Loading Small, Critical UI Images
Not every image is a performance problem.
Lazy loading tiny assets can be counterproductive.
Examples:
- Icons
- UI decorations
- Rating stars
- Badges
These images:
- Load quickly anyway
- Are often needed immediately
- Add unnecessary observer overhead when lazy loaded
Rule of Thumb
If an image is:
- < 5–10 KB
- Above the fold
- Part of UI feedback
Do not lazy load it.
Pitfall 4: Lazy Loading Images Inside Sliders or Carousels
Sliders often:
- Inject images via JavaScript
- Change visibility dynamically
- Control layout timing
Combining sliders with lazy loading frequently results in:
- Images loading too late
- Broken LCP detection
- Flash of empty content
Better Pattern for the First Slide
- First slide: eager load
- Subsequent slides: lazy load
<?php
$attrs = array(
'loading' => $is_first_slide ? 'eager' : 'lazy',
);
?>
Pitfall 5: Lazy Loading CSS Background Images
CSS background images are not affected by native lazy loading.
Developers often try to simulate lazy loading with JavaScript.
Problems:
- Browser can’t prioritize background images well
- LCP optimization becomes unreliable
- Extra JS execution delays rendering
For critical visuals, prefer:
<img>+object-fit<picture>for art direction
Pitfall 6: Lazy Loading Images Needed for CLS Stability
If an image:
- Defines layout height
- Reserves space visually
- Prevents content jumps
Lazy loading it without proper dimensions can worsen CLS.
Always Provide Dimensions
Use WordPress helpers that output width/height automatically:
<?php
echo wp_get_attachment_image(
$id,
'medium'
);
?>
Avoid stripping width and height attributes in themes.
Pitfall 7: Blindly Lazy Loading Everything via Filters
Some themes or snippets force lazy loading globally:
<?php
add_filter( 'wp_get_attachment_image_attributes', function ( $attr ) {
$attr['loading'] = 'lazy';
return $attr;
} );
This breaks performance for critical images.
Correct Pattern: Opt-Out, Not Opt-In
<?php
add_filter( 'wp_get_attachment_image_attributes', function ( $attr ) {
if ( empty( $attr['class'] ) ) return $attr;
if ( strpos( $attr['class'], 'no-lazy' ) !== false ) {
$attr['loading'] = 'eager';
}
return $attr;
} );
Then mark critical images explicitly:
<img class="hero-image no-lazy" ...>
When Lazy Loading IS a Good Idea
Lazy loading works best for:
- Long-form content images
- Below-the-fold galleries
- Archive pages with many thumbnails
- User-generated content feeds
In other words: content the user may never scroll to.
Recommended Theme Strategy
- Identify the LCP image and force eager loading
- Eager load logos, icons, and UI images
- Lazy load only clearly below-the-fold images
- Never lazy load the first visible image in a layout
- Use class-based control, not global overrides
Checklist: Should This Image Be Lazy Loaded?
- Is it above the fold? → No
- Is it the LCP candidate? → No
- Is it small and UI-related? → No
- Is it inside a slider’s first view? → No
- Is it below the fold and non-critical? → Yes
Summary
- Lazy loading is not a universal optimization
- Applying it to LCP images hurts Core Web Vitals
- Above-the-fold and UI images should load eagerly
- Global lazy loading filters are dangerous
- Intentional, scoped lazy loading delivers the best results
Performance optimization is about prioritization.
Lazy loading should be applied selectively—never automatically.
🎨 Want to learn more? Visit our WordPress Customization Hub for tips and advanced techniques.