Features
Media Optimization
Media optimization reduces the performance impact of images, iframes, and embedded videos on your pages. Images typically account for 50-70% of a page's total weight, so optimizing how they load has an outsized impact on perceived performance.
LazyLoad
LazyLoad defers loading of images, iframes, and CSS background images until they are about to enter the viewport (the visible area of the browser window). Instead of loading all images when the page first loads — including ones the visitor may never scroll to — only visible and near-visible images load immediately.
How it works
The plugin replaces the src attribute with a placeholder and adds the real URL as a data attribute. A small JavaScript script monitors scroll position and swaps in the real source just before the image scrolls into view.
What gets LazyLoaded
<img>tags in post content, widgets, and theme templates<iframe>embeds (maps, videos, third-party widgets)- CSS background images (detected via inline styles and stylesheets)
What does NOT get LazyLoaded
- The Largest Contentful Paint (LCP) image (auto-detected)
- Above-the-fold images
- Images in the header/logo area
- Images you explicitly exclude via CSS class or URL pattern
LCP and Above-the-Fold Exclusion
The LCP image is the largest content element visible when the page first loads. LazyLoading it would delay the LCP metric — the opposite of what you want. The plugin automatically detects and excludes the LCP image from LazyLoad.
You can also exclude specific images by adding their CSS classes or URL patterns to the exclusion list in the Media tab.
Automatic Image Dimensions
Images without explicit width and height attributes cause Cumulative Layout Shift (CLS) — content jumps around as images load and the browser discovers their dimensions. With Media → Image Dimensions → Add Missing Width/Height on, the plugin adds the missing attributes so the browser can reserve the right space before the image arrives.
It runs over the whole page, not only post content, and only on images that carry neither width nor height already. Where WordPress knows the image — a media-library image carrying its wp-image-<id> class — the size is read from the attachment record for the exact file named in src, so a thumbnail gets the thumbnail's size rather than the original's. For images outside the media library, such as theme and page-builder assets, the file itself is measured; the plugin will not guess when the tag carries a srcset, because any of those candidates might be the one the browser renders.
Every image the plugin stamps is marked data-cachingout-dim="1" in the page source. That is the quickest way to confirm whether a particular image was changed by the plugin: view source and search for it.
Why this does not resize your images
width and height on an <img> are presentational hints. They sit below every stylesheet rule in the cascade, so a theme rule such as .site-header img { height: 60px } always beats them. The attributes only decide an axis your CSS leaves at auto — which is what makes them safe for reserving space.
The exception is a theme that sizes an image on one axis and never sets the other to auto. A logo constrained by max-width: 100% with no height rule would take the injected height as its real height and render at the file's full size, pushing out the bar it sits in. To prevent that, whenever the plugin adds dimensions it also emits one small rule:
@layer cachingout { img[data-cachingout-dim] { height: auto } }
It sits in a CSS cascade layer, and unlayered CSS always wins over layered CSS whatever its specificity — so this rule can never override your theme. It only fills in height: auto where your theme sets no height at all. Reserved space is unaffected: the browser still derives the aspect ratio from the attributes, so CLS protection is unchanged.
To remove the rule entirely:
add_filter( 'cachingout_dimension_style', '__return_empty_string' );
Excluding an image from dimensions
Any of these leaves an image completely untouched, dimension attributes included:
- add the
no-lazyorskip-lazyclass to the<img> - add
data-no-lazy="1"to the<img> - add part of its file name or one of its classes to the LazyLoad exclusion list in the Media tab
Before 1.21.7 these stopped lazy-loading but not dimension injection. If you excluded an image on an older version and it was still being resized, that is why.
When an image is re-processed
If an image-optimisation plugin (Imagify, ShortPixel, Smush, EWWW) converts or resizes a file, dimensions already written into cached pages would describe the old file. The plugin clears the page cache whenever attachment metadata changes, so the next visitor gets freshly measured pages. A bulk optimisation run triggers one purge per batch rather than one per image.
WebP and AVIF (Pro)
WebP and AVIF are modern image formats that are usually smaller than the same image as a JPEG or PNG. Delivery does not convert your images by itself: it serves copies that already exist, made by an image conversion plugin, by your host, or by Pro's own Image compression, one image at a time. Switch the formats on under Media > Next-gen images.
How it works
- When a page is cached, Caching Out also stores a copy of it whose images point at their WebP copies, and, with AVIF on, a copy whose images point at their AVIF copies (or the WebP copy where an image has no AVIF one).
- A browser that announces AVIF gets the AVIF page, one that announces WebP gets the WebP page, and every other browser gets the page with your original images. The order visitors arrive in makes no difference.
- Safari can display both formats but does not announce them when it asks for a page, so it receives the WebP page or the original images. That is expected and harmless.
- Pages whose images have no copies are stored once, for everyone.
Which copies are recognised
photo.jpg.webpbesidephoto.jpg(the layout most converters use)photo.webpbesidephoto.jpg, unless another original such asphoto.pngshares the name- a separate
wp-content/uploads-webpc/folder holding the same paths - the copies Pro's Image compression makes, in
wp-content/cachingout-images/
A copy is never used when it is larger than the original, or older than it (a replaced original whose copy was not remade). Images on your CDN hostname are matched too, and lazy-load attributes from other plugins (data-src, data-srcset, data-lazy-src) are rewritten along with src and srcset.
Checking it
With CACHINGOUT_DEBUG on, every cached response carries X-CachingOut-Image-Variant: avif, webp or none.
Image compression (Pro)
Caching Out Pro can make a heavy JPEG, PNG or WebP image smaller, one image at a time, on your own server: you see it before and after, and the smaller file keeps the same URL, with an exact backup to restore. Pick images on the Page Audit ("Compress this image") or in the Media Library, then review them on the Image compression tab. Everything about it is on its own page: Image compression.
LazyLoad Videos
Self-hosted <video> elements are often the heaviest request on a page. With LazyLoad Videos on, the plugin moves each <source src> to data-src, marks the element with data-cachingout-video, and restores the source only when the player scrolls near the viewport. A playing video is paused when it scrolls away and resumed when it returns. A video with the autoplay attribute is started (muted) when its source is restored.
Videos the theme controls itself
Some themes do not use the autoplay attribute. Instead an inline script calls video.play() on DOMContentLoaded (typically a muted, looping promo clip with preload="none" and a custom play button). With LazyLoad Videos on, that call runs before the source has been restored, the browser rejects it, and the theme shows its fallback play button — or nothing plays at all, on desktop and mobile alike.
Fix, in order of preference:
- Put the
autoplayattribute on the<video>and delete the theme's inlineplay()call. LazyLoad Videos convertsautoplayintodata-autoplay="1"and starts the clip muted when it scrolls into view. The theme gets the behaviour it wanted, and the file stays out of the initial page load. - Only if you cannot edit the theme: add
data-no-lazy="1"to the<video>(or theno-lazyclass), or add a fragment of the file name to the LazyLoad exclusion list.
Option 2 has a real cost, so reach for option 1 first. Handing the element back to the theme means the theme's play() call runs at page load, and an explicit play() defeats preload="none" – the browser downloads the clip immediately. Measured on a live site: a 10-second promo video pulled 2.3 MB during page load and became the entire media budget. If you must use option 2, add a poster frame and re-encode the clip; a 10-second web loop should be a few hundred KB, not megabytes.
YouTube Placeholder
Replaces YouTube iframe embeds with a static thumbnail image. The actual video player only loads when the visitor clicks the thumbnail. This eliminates the ~1-2MB of JavaScript and resources that YouTube embeds load on every page, even when the visitor never plays the video.
Troubleshooting
Images above the fold are loading late. Add their CSS classes to the LazyLoad exclusion list. Look for the image wrapper's class in your browser inspector.
My logo or header image is LazyLoaded. Add the relevant CSS class to the exclusion list. Header images are normally auto-excluded, but custom themes may use non-standard markup.
My logo or header image became larger, or its container stretched, after I enabled Caching Out. Automatic Image Dimensions added the image's real file size as width and height, and your theme sizes that image on one axis only, leaving the other to be decided by those attributes. View source: if the tag carries data-cachingout-dim="1", that is what happened. From 1.21.7 the plugin ships a companion height: auto rule that prevents this without overriding your theme, so upgrading is the first thing to try. If it persists, the durable fix is height: auto in your own CSS for that image; otherwise add data-no-lazy="1" or the no-lazy class to the image, or add it to the LazyLoad exclusion list, or turn off Media → Image Dimensions → Add Missing Width/Height. See "Automatic Image Dimensions" above.
An image I replaced or optimised still shows its old size. Cached pages carry the dimensions measured at the time they were cached. The plugin purges the cache when attachment metadata changes; if you replaced the file on disk without going through the media library, purge the cache manually from the Dashboard.
A self-hosted promo or background video no longer plays (desktop and mobile). The theme starts it with video.play() at page load, before LazyLoad Videos has restored its source. Best fix: give the <video> the autoplay attribute and remove the theme's inline play() call, so the plugin defers it properly. Excluding it with data-no-lazy="1" also restores playback but pulls the whole file into the initial page load. See "Videos the theme controls itself" above.
YouTube videos stopped working. The thumbnail placeholder replaces the iframe. Click the thumbnail to load the video. If the thumbnail doesn't appear, check your theme for JavaScript that modifies iframes on page load.