Background images are evil

Learn why to avoid background images on your website, how to quickly find background images and how to fix this issue

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

Background images are evil

Those of you that ik now me or have heard me speak might have heard me talk about background images. Those of you who have not: I really really do not like background images. In this article I will quickly explain why don't like background images, how to quickly find pages with background images and how to fix them!

Why background images are bad for the Core Web Vitals

When loading a web-page every element has it's time and it's place. With some modern techniques like deferring, preloading, async loading, scheduling, defining the fetchpriority etc etc we can get all critical resources pretty much under control. Except for background images! 

Consider this real-world example:

On a daily basis, mostly in WordPress sites I see this pattern. All the normal images are lazy loaded and some images (in this case the social icons in the footer) are background images Can you guess what happens?

<html>
<head>
    <style>
        footer {
            /* a margin of 100 vh wil make the footer off-screen !*/
            margin-top: 100vh;
            >.social {
                >.facebook {background-image: url('img/facebook.jpg');}
                >.instagram {background-image: url('img/instagram.jpg');}
                >.linkedin {background-image: url('img/linkedin.jpg');}
                >.email {background-image: url('img/email.jpg');}
            }
        }
    </style>
</head>
<body>
    <!-- yes this image is lazy loaded, because tiny mistakes happen! -->
    <img loading="lazy" src="img/hero.jpg"></img>
    <footer>
        <div class="social">
            <span class="facebook"></span>
<span class="instagram"></span>
<span class="linkedin"></span>
<span class="email"></divspan
</div> </footer> </body> </html>

You might have guessed it: the offscreen background images are queued for download before the far more important 'hero.jpg' image which will usually become the largest contentful paint element on the page.

lazy lcp with bg img

But that is not all!

As I said background image are evil! That is because, aside from the weird priority that they sometimes get background images lack the cool features that normal images get!

  • No lazy loading: there is no loading attribute for background images
  • No async decoding: there is no decoding attribute for background images
  • No fetchpriority: there is no fetchpriority attribute for background images
  • Responsive image sources: The image-set() attribute for background images does not have the same power of features that you get with good responsive design.
  • No width and height attribute. Not being able to set the simple width and height attribute will make you use workarounds that require code (more code is always slower then less code with the same complexity!)
  • No alt text: while this does n

Quickly find all background images on a page

So how do we find out if a webpage has background images on them? Well you could check out the network inspector, filter on images, right clock the menu bar, enbable the initiator columsn and check the initiator but it is far easier to paste this code into the devconsole.

Simple open the dev console with Ctrl-Shift-I, navigate to the console tab and paste this code. It will show you all the background images on the page
let bgimg = performance.getEntriesByType('resource')
  .filter(rs => rs.initiatorType == 'css')
  .map(rs => {
  return {
    name: rs.name,
    initiator: rs.initiatorType
  }
}) || [];

(bgimg.length > 0)?
    console.table(bgimg):
    console.log('No background images on this page!');

This will show you a cleanly formatted table with all the background images names and the initiators

background img console table

How to avoid background images

Background images are easily avoidable. How to do this depends on the image itself. There are roughly 2 methods.

In case of 'normal images'

You would not believe it if I told you but the majority of the cases where I find background images the background part of the image does not even have a purpose. The images just 'need to be somewhere on the page' and the background-image:url() is misused for this purpose.
If this is the case just add a normal image tag and remove the background image from the stylesheet.

In case of cover images:

Cover images ar eimages that completely cover a parent container. Using background images as cover images sort of makes sense because a long time a gho this used to be the only way to get cover images and I guess people just stick to what they know. Fortunately there are better options available to us. So let's fix it!
In case of cover images just remove the style   background-image: url(hero.jpg); background-size: cover;a and place a normal image in that same container and edit the CSS to look like this:

<style>
.img-container {
    position: relative;
    > img {
       width: 100%;
       height: 100%;
       object-fit: cover;
       position: absolute;
       z-index: 1;
   }
}
<style>

<div class="img-container">
  <img 
       height="500" 
       width="300" 
       decoding="async" 
       loading="lazy" 
       src="hero.jpg"
       srcset="hero-320w.jpg, hero-480w.jpg 1.5x"
       alt="alt text"
       fetchpriority="low"
  >
</div>


I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

Background images are evilCore Web Vitals Background images are evil