With content on the web getting longer, it’s important to take advantage of features like lazy load in WordPress to keep your site running fast.
What is lazy loading?
Lazy loading is essentially delaying or deferring the loading of images until a user scroll downs the page (images enter within the viewport).
Why is this awesome? Well, let’s say you have a long-form blog post with 100 images in it. By default, the browser will try to load all 100 of those images when someone visits the post. Even with optimized images, this can take a while, especially on mobile.
But if you lazy load the images, it will only load the images towards the top of the page that visitors can see in their browser. The number of images varies based on the type of browser, what type of lazy loading is being used, the size of the viewport, etc. But regardless, the idea is that it usually cuts down on 85%+ of the requests right off the bat.
Beyond requests, lazy loading will also fix the “Defer offscreen images” warning you get from PageSpeed Insights.
Lazy load test
We ran a little test on one of our blog posts so you could see the difference.
Not lazy loaded
Here is before we lazy-loaded the images. As you can see, the are a total of 56 requests, total page size of 852 KB, and load time of 1.2s.
Lazy loaded
Here is after we enabled lazy-loading. As you can see, the number of requests dropped down to 35, the total page size decreased to 245 KB, and the load time dropped to 0.8s. So in other words, just enabling lazy loading gave us a speed increase of 33% and decreased the page size by 70%.
The post we tested on was fairly optimized already. You’ll see even bigger speed increases if you are lazy loading unoptimized images or have more images on a page.
How our lazy loading works
We use a small (2.5 KB), open-source JavaScript library for lazy loading images, iframes, etc. We also support lazy-loading WebP files. You will see a request to the following file on your site:
/perfmatters/js/lazyload.min.js
Perfmatters lazy loading vs native lazy loading
WordPress 5.5 now has native lazy loading by default. However, we recommend using the lazy loading solution in Perfmatters. Why? Our solution is faster and better than native lazy loading for the following reasons:
- Native means it’s letting the browser decide what should be lazy loaded. Unfortunately, with that is the problem that, by default, it’s way too eager. This can be an advantage as you probably won’t need any exclusions, but in general, not as many resources will be lazy loaded. This means it won’t be as fast.
- Images have to be uploaded into the WordPress media library and also have width and height added. This means native lazy loading will probably not get applied to everything.
- Background images in CSS are not supported by native lazy loading.
- Native lazy loading is making improvements but still lacks support for certain things. We’ve been adding a lot of features to ours, as you can see below.
Important: When lazy loading in Perfmatters is enabled, the default native lazy loading in WordPress is automatically disabled.
How to enable lazy load in WordPress
Before enabling lazy loading in Perfmatters, ensure you have turned it off everywhere else, such as other optimization plugins or your theme.
To enable lazy load in WordPress, go to the “Perfmatters” settings in your WordPress admin dashboard.
Click on the “Lazy Loading” submenu.
There are a few different options you have when it comes to lazy loading. They can also be used together at the same time.
Lazy load images
The first option and most common is to lazy load on your images. To enable this, toggle on the “Images” option. This also includes inline background images inside the style attribute.
Exclude leading images
You can manually exclude images from lazy loading, but sometimes it’s easier to automate the process. That’s where the “Exclude Leading Images” feature comes into play. This allows you to automatically exclude a certain number of images starting from the top of the page (above the fold).
Important: Make sure you are logged out when estimating or testing the number of images you want to exclude. Automated exclusions don’t work on background images.
If you’re using our preload critical images feature, this will automatically exclude those images from lazy loading. Meaning you might not need to use exclude leading images.
Lazy load iframes and videos
The second option is to lazy load iframes and videos. This includes YouTube, Vimeo, SoundCloud, Google Maps, and any type of iframe. This also works with videos embedded with a file URL using the video
tag.
To enable this, toggle on the “iFrames and Videos” option.
YouTube preview thumbnails
If you’re using YouTube videos on your site, it can be advantageous to enable our preview thumbnail feature. What this does is swap out the YouTube iframes with a preview thumbnail and lightweight SVG play icon. The iframe is then loaded on click. This is the fastest way to load YouTube videos and will fix the TBT overhead from videos.
In our performance testing with videos, we saw this feature increase the speed of the site by 64%. It also dropped the total page size by 58%. That’s pretty incredible.
- Before: 1.93s load time with a total page size of 691 KB.
- After (lazy load on): 0.72s load time with a total page size of 288 KB. It also decreased LCP by 44.19%, TBT by 99.63%, and FCP by 22.73%.
The thumbnail used on YouTube is the preview image that will automatically be pulled. This is just an example below.
To enable this, toggle on the “YouTube Preview Thumbnails” option. Note: This does require iFrames and Videos to be enabled in Perfmatters.
YouTube preview thumbnail quality filter
By default, a low-resolution image is pulled from YouTube for the thumbnail. We have a filter you can use to change the quality of the thumbnail. The maxresdefault
attribute will pull the highest quality if available. Make sure your YouTube thumbnails are at least 1280 x 720 pixels. Check out this great guide on how to size your YouTube thumbnails. See additional options for the filter.
add_filter('perfmatters_lazyload_youtube_thumbnail_resolution', function($resolution) { return 'maxresdefault'; });
You can also use the wp_is_mobile
function to show low-resolution images on mobile devices while showing high-resolution thumbnails on a desktop.
add_filter('perfmatters_lazyload_youtube_thumbnail_resolution', function($resolution) { if(!wp_is_mobile()) { $resolution = 'maxresdefault'; } return $resolution; });
DOM monitoring
DOM monitoring watches for changes in the DOM and dynamically lazy loads newly added elements. This improves compatibility with third-party plugins and themes that utilize features like infinite scrolling, gallery sliders, carousels, etc…
To enable this, toggle on the “DOM Monitoring” option.
Note: If you aren’t using any functions that will dynamically add new images to the page, we don’t recommend enabling this option.
Exclude images from lazy loading
There may be times when you will want to exclude a specific image from being lazyloaded. There are a couple of ways to do that.
Exclude using Perfmatters UI
The easiest way is to use the UI in Perfmatters. Exclude an element by adding the source URL (example.png) or by adding any unique portion of its attribute string (class=”example”). Format: one per line
If you have a plugin like ShortPixel or Imagify serving WebP images you might need to target the <picture>
tag.
Here are a couple of examples:
- If you’re using a theme like GeneratePress and want to exclude the logo from lazy loading, you can add their
is-logo-image
class. - If you’re wanting to exclude featured images from lazy loading in your blog posts, you can use their thumbnail class, for example
class="attachment-full size-full
.
Exclude by Parent Selector
Many featured images, galleries, etc., above the fold, don’t have a unique class on their image tags. This can sometimes make them hard to exclude globally. However, their parent container almost always has a pattern or unique string you can match.
You can exclude specific images from lazy loading by adding any unique portion of an attribute string (class=”example”) from a parent container. This feature requires Advanced Options to be enabled.
no-lazy CSS class
If you have access to add a CSS class to the specific image you are wanting to exclude, simply add the no-lazy
class and it should be ignored when the document is being prepared for lazyloading.
perfmatters_lazyload_excluded_attributes filter
If the image you want to exclude is a bit harder to access and manipulate directly, we have a WordPress filter available which can be used to add any attributes or portions of attributes that are specific to the image in question.
In the example below, we are targeting any images that contain either the title='Perfmatters'
attribute or the partial class='size-full
attribute. This is simply a string match, so any portion of any attribute should work, it just needs to be an exact match for the image or images you are wanting to exclude.
function perfmatters_lazyload_exclude_attributes($attributes) { $attributes[] = "title='Perfmatters'"; $attributes[] = "class='size-full"; return $attributes; } add_filter('perfmatters_lazyload_excluded_attributes', 'perfmatters_lazyload_exclude_attributes');
Here is an example of an exclusion based on an image file name match.
function perfmatters_lazyload_exclude_attributes($attributes) { $attributes[] = 'src="https://domain.com/image.png"'; return $attributes; } add_filter('perfmatters_lazyload_excluded_attributes', 'perfmatters_lazyload_exclude_attributes');
This filter can be used in a variety of ways, please reach out to us if you have any questions.
Exclude page/post from lazy loading
You can exclude an individual post, page, or custom post type from lazy loading. In the editor, on the right-hand side uncheck “Lazy Loading.” This will exclude the entire page from the script.
How to change the viewport threshold
If needed, you can extend the lazy loading threshold allowing images to load before they are visible in the viewport. By default, it’s 0px, which is the most aggressive and best for performance. However, some might prefer to increase this as it can make scrolling a little smoother. Or in other words, there will be fewer pop-in of images as you scroll down the page.
The threshold field accepts px or %.
You can also use the following filter to change the viewport threshold for lazy loading. It accepts px
or %
.
add_filter('perfmatters_lazyload_threshold', function($threshold) { return '500px'; });
Note: On sites with a lot of third-party JS (for example, those running ad networks like Mediavine or AdThrive), we recommend setting the viewport threshold to at least 300px.
Fade in
Some users like to have a fade in effect on images when scrolling down a page. This creates a smoother transition for images instead of just popping in immediately after they are lazy loaded. To enable this, toggle on the “Fade In” option.
If you want to change the fade in transition speed, you can do that with our #perfmatters_fade_in_speed filter.
CSS background images
Perfmatters supports lazy loading inline background images without any additional configuration. However, some page builders, themes, and plugins load background images in their (CSS) stylesheets. Perfmatters cannot change the contents of their CSS, but we can prevent certain containers from immediately loading their background image in the browser. This enables you to lazy load CSS background images in things like GenerateBlocks, Elementor, Oxygen, Divi, Beaver Builder, etc.
To enable this, toggle on “CSS Background Images.
In the Background Selectors box, input a specific ID or class found on the container (or parent) that contains the background image. Format: one per line, without the prefix (.
, #
). We support the following selectors: div
, section
, figure
, footer
Note: Some solutions like GenerateBlocks let you switch the background image to inline, in which case, lazy loading would work automatically.
Adding class
Some page builders and themes might not have unique classes on their divs containing the background images. And you don’t want to lazy load your hero images or those above the fold. In this case, if you have access to add an additional class to the container itself, you can add our perfmatters-lazy-css-bg
class instead. For example, in Elementor, you add it in the CSS Classes field on the div containing the background image.
Forcing an element to lazy load
There may be times when an element coming from another plugin or theme already has an exclusion class or attribute applied that prevents our lazy load from picking it up by default. If this happens, you may be able to force that element to lazy load with the following filter.
perfmatters_lazyload_forced_attributes filter
This filter can be used the same as in the excluded attributes example, but when an element contains one of the included attributes, our lazy loader will skip checking that item for exclusions and continue attempting to lazy load that element.
function perfmatters_lazyload_force_attributes($attributes) { $attributes[] = "title='Perfmatters'"; $attributes[] = "class='size-full"; return $attributes; } add_filter('perfmatters_lazyload_forced_attributes', 'perfmatters_lazyload_force_attributes');
Troubleshooting
If you’re having trouble with images loading, here are a few troubleshooting tips.
Turn off other lazy loading solutions
Make sure you aren’t using multiple lazy loading solutions at the same time. This can cause conflicts and things not to work properly. This includes lazy loaders in other optimization plugins and solutions like Cloudflare Mirage. Or page builders like Bricks.
Image source showing as SVG code
If your images aren’t loading when lazy load is enabled, and the source for the image looks something like below, it means you’re probably deferring our lazy loading script.
data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0'%0%0/svg
To fix this, you will need to exclude the /perfmatters/js/lazyload.min.js
from deferring.
Unable to lazy load CSS background image
If a theme or page builder is using an !important
class on the background image, this trumps all, and there isn’t anything we can do. Using an !important
class on everything is bad practice and should only be used as a last resort.
Extra space above or below YouTube preview thumbnails
If you’re experiencing extra space above or below the YouTube preview thumbnail, it’s most likely the theme or page builder is using the same method we are for their video container. You can fix this with a little CSS. Here are a few examples.
Bricks
.brxe-video .perfmatters-lazy-youtube { margin-top: -56.25%; }
Oxygen
.oxygen-vsb-responsive-video-wrapper .perfmatters-lazy-youtube { margin-bottom: -56.25% }
Working with a GDPR plugin
If you’re using our YouTube preview thumbnails feature along with GDPR plugins, they might block things from loading. For example, with the Complianze plugin, you’ll need to exclude the following iframe from lazy loading in Perfmatters.
cmplz-iframe