It’s been over six years since we added lazy load support to EWWW IO, and now we’re taking it up a notch (or three) with EWWW Image Optimizer 8.3. See what I just did there? Did ya?

Lazy Background Images

There are a lot of improvements to the lazy loader, but the biggest improvement is adding support for background images in external CSS files. Yeah, I know, you could already do that, sort of. However, now EWWW IO can specifically target the exact elements that have background images, instead of adding the ‘lazyload’ class “en masse” based on a class or similar attribute. I have to give WP Rocket some credit here for their solution to this problem, as they were the first (to my knowledge) to even attempt this. Having their example made this somewhat easier–it still wasn’t easy though.

element with a CSS background image
See the background image? Me neither, but SWIS can find it!

Short version, we use the CSS parsing engine in SWIS Performance to scan all CSS files, including internal <style> blocks, and replace background images with CSS variables. On the front-end, EWWW IO then takes the list generated by SWIS, and uses it to tag each element for lazy-loading.

CSS variable for background image

Once that is done, not only can EWWW IO lazy load those images, but it can auto-scale them and also provide WebP versions of images in external CSS. Of course, using Easy IO is the… well, easier way, but now you can get WebP images for all CSS background images even if you don’t want to use a CDN! Either way, EWWW IO is the only plugin that lets you do WebP Conversion and Automatic Scaling for background images in external CSS.

Speed Improvements

We were able to make a few different improvements to the speed of the lazy load function in this release. The first we kind of already talked about, as being able to target the exact elements with background images is much more performant than blindly tagging a whole bunch of elements with the ‘lazyload’ class. The second improvement is in the parsing of the HTML, which is kind of boring, but involves using the PREG_OFFSET_CAPTURE flag, in case you were dying to know.

The third came about unexpectedly when one of our long-time users noticed an issue with lazy loading on Safari. Specifically, the right-sized PNG placeholders that EWWW IO generates via ImageMagick sometimes don’t load in Safari.

broken image placeholder
A sad image that can’t load…

After a whole lot of trial and error, I discovered that the PHP GD extension would produce placeholder images that worked every time. This was previously the fall-back in case ImageMagick wasn’t available, but now those roles have been reversed. Bonus: GD generates the PNG placeholders faster than ImageMagick, hurrah!

More Consistency

For quite a while, we’ve been thoroughly annoyed that Google’s PageSpeed Insights tool would yell at folks for images being 2x too large. Why? Because PSI was specifically testing with an (emulated) device that has a 2x screen. What? Surely they wouldn’t complain about getting 2x images for a 2x screen? Yeah, they really did… To be fair, it’s bothered me for a while that we’re trying to eek out every last bit of performance for mobile devices, and then we send them images that are 4-9x larger than the display space. I mean, they get what they ask for, right?

Well, not any more… A while back, we introduced a High-DPI setting for Easy IO that partially addressed this, but the browser was still responsible for choosing a 1x, 2x, or even 3x image–specifically when dealing with srcset/responsive images. With version 8.3, that is now up to you as the site admin. If you really want 2x and 3x images on your site, by all means enable High-DPI images via Easy IO. Otherwise, the default setup will deliver nice lean 1x images, which will be great for mobile devices, and stop PSI from whining so much.

Another Easy IO setting that got some attention is the Premium/Lossy option. In the past, it was possible for some images to still be delivered in Lossy mode, even if you turned off that option. The CDN needed to see the lossy=0 parameter in the URL, otherwise it went back to Lossy mode. We’ve moved this setting into the zone configuration now so it can be applied for every single image on your site, with no misses.

Honorable Mentions

Speaking of things that bother me, what’s up with the WordPress block editor applying classes to a parent element instead of the <img> element? That’s been a constant source of issues for folks who want to bypass lazy loading for above-the-fold images with the ‘skip-lazy’ class. EWWW IO 8.3 now checks the direct parent element of every <img> so you can add ‘skip-lazy’ right in the block editor.

Oh, but I’ve got more! The image sizes generated by WordPress have this lovely gap between the medium (300px) and large (1024px) versions. So they added the medium_large size at 768px. Problem solved, right?! Maybe it’s just me, but I’m constantly finding images that are just over 300px, so the browser loads the 768px version, wasting more than 75% of those pixels, ugh… Don’t get me wrong, WP generates plenty of sizes, and I’m glad they aren’t adding another. Instead, we can now use Easy IO to fill in a 450px version, with no extra files or space on your server.

If that isn’t enough for you, there’s a couple other fixes, and the standalone Easy Image Optimizer plugin got a small UI refresh. Check it out, and let us know what you think!

Easyio toon car with text