Fix Largest Contentful Paint Image Was Lazily Loaded Error on Shopify Theme

Taylor wearing black jacket, white shirt with arms in the air. Text: Fix Largest Contentful Paint Image was Lazily Loaded Error on Shopify Theme.

Making Shopify themes faster is something that has become increasingly important. Not only does Google care about the performance of your website, but more importantly your users do too.

In this video, we'll walk through one of the simplest performance wins you can implement into your Shopify theme that proves to carry the greatest benefit - improving the Largest Contentful Paint (LCP) metric.

In many instances, Shopify themes are implementing best practices with lazy loading images. This ensures that resources aren't called until they are needed when a user scrolls to the image on the page. However, this is not something we want to implement when the image is "above the fold" or immediately in the viewport when the page loads.

This is because of the importance of the LCP.

Making sure the LCP, most often cases (but not always) an image, loads quickly ensures that we can take full advantage of performance benefits with below the fold images not impacting a fast load for above the fold content.




Speed optimization on Shopify can be kind of difficult sometimes and a lot of times we're really focused on that page speed score number. I've talked at length about why it's more important to focus on the core web vitals instead. But, one of the big wins that we can get today is helping improve those core web vitals, specifically the metric, Largest Contentful Paint. Because of how heavily it's weighted in the page speed score, you're also going to see some of your biggest improvements in your page speed score itself as well that way. In order to do that, let's take a look at one quick trick on how to make this not only something that can be fixed but easily accessible for merchants in the future while they're adding new content to pages. Let's check it out.

Example of LCP Lazily Loaded vs Not

I want to give you all an example here of what this metrics looks like. Now, granted this 81, this is from running this locally, so obviously these numbers are going to look fantastic in here. But, if you take a look at this 81, might think that's great, right? We scroll down here. You can see though the Largest Contentful Paint, not a great load time. If you scroll down even further, we get this issue that the Largest Contentful Paint image was lazily loaded. That's something we obviously want to fix, something that I do regularly for merchants. Then also, obviously data on my own site was built in some controls here so that way we can opt in or out of the lazy loading for this Largest Contentful Image.

Does it make a big deal of a difference? You tell me. Here's a real quick comparison when it's enabled versus when it's not enabled. So, an 81 for when lazy loading is occurring in that Largest Contentful Paint and then a 93 when it's not enabled. To verify real quick, we don't have that issue popping up as a potential problem. In one of those, I enabled lazy loading for this Largest Contentful Image. Then, in another instance, we've got it turned off. You can see that there's some pretty big performance benefits to be found just by enabling or disabling lazy load during the course of that. In order to do that on Shopify, we can take an example here in the Dawn theme.

LCP and Why It’s Important

First, just real quick to show you why this is a really great performance win. You can see here, this is in version 10 for the Lighthouse Scoring Calculator, it's at 25%. Pretty much as soon as the Largest Contentful metric was introduced, it's pretty much consistently been 25% of that weighted score. Older versions didn't actually have this First Meaningful Paint was one of the things that they recommended. It was kind of like a mixture between these two. Since this has been around, it is one of the core web vital metrics, key core web vital metrics.

If you want to learn more about that, I'll have this link in the description. This talks about what the Largest Contentful Paint, essentially right here is what you want to pay attention to. It's the time of the largest image or text block visible within the view port, so that initial above the fold load here relative to when the page first started loading. It goes on to talk a little bit more about this and things that you can optimize. For now, just understand what the metric is and then it's one of the key metrics that we need to focus on both for a win for core web vitals, since it does show up as one of those that we need to focus on. Then, as well, it's a great win for merchants because of that page speeds score that everybody's so focused on. It's a very heavily weighted metric.

How to Opt In/Out of Lazy Loading

To give you an example here, we're going to work with just a general Shopify theme here, and this is Dawn version 8.0. What we're going to do here is we're going to make this really simple because right now there's some best practices involved where the images are all being lazy loaded. Which again, best practice from the standpoint of a majority of your content is going to be below the fold. However, we want to build in some controls here where maybe we can turn that off for anything that's going to be above the fold. We probably don't want to call it something like Largest Contentful Paint Image or Asset or something like that. We need to make this simple, easy enough for merchants who are going to use their own language to kind of describe this stuff. Above the fold is a pretty common tactic that I'll use just because most people when you're talking to them, know what that's about.

Real quick, let's jump into the code here, and we're just going to add a little checkbox here to conditionally turn that off and on. If you scroll over here into sections in your files, let's find the image with text. I'm using the images with text, but you can obviously utilize this same technique for most of the sections where there's image assets and those sorts of things being loaded in. This is a common technique that you can employ across here. As I'm scrolling around, whoops, got a little aggressive on my scroll here. We're going to try to find the image option in here. You can see here that there is an image right here and there is a lazy loading option. We're going to be using this here to display our image. That's where we want to look at adding some controls. Let's scroll down, and we really want to put these controls in the main section settings because that's where the image itself is.

Let's go on back to this section. If you click into the section settings, that's how you set the image that's in here. It's not in a block or anything like that. We're going to want to add that here, and we'll probably want to add it somewhere... Let's choose maybe directly beneath some of these other specific items here. Just right under the image might be the easiest thing to do. Here's our image picker. What we want is to go ahead and add "type," "checkbox," "id." Maybe we want this to be on here. We'll want to "disable lazy load" and then "label" and then we'll say, "above the fold image." Just as simple as that, don't forget your little comma here. We'll go ahead and save. If you're wanting to add something in here to include some additional information about what this looks like. We could add some additional content here. But for now, let's just make sure that this works. Go ahead and refresh the page.

You can see here that we do have an above the fold we can check mark off and on. But, it doesn't look like we really are probably getting any kind of a benefit here. Obviously, because we haven't checked this into anything. We've not actually hooked this up to code anymore.

Tag Filter Option via Liquid

Let's dive back into the code here. This is really simple when it's just a simple image tag or whatever, but right now what they're using is the new image tag filter option. In which case, we're doing this all via liquid. Which is okay, we can just do it this way as well. If you want real simple, there's obviously better ways to write this, but we're going to do this the most simple way here with just a liquid conditional. So, "if section.settings.disable lazy load," which is what we called this earlier.

I like to go ahead and just go ahead and write all these guys out ahead of time. Because otherwise, I might accidentally forget to include these. So, I'm going to go ahead and remove these. This is all usually a lot prettier in the editor, so bear with me here while I fix some stuff so that way it's not too hard to look at. But essentially, you want to just use the exact same liquid conditional here or liquid tag, I'm sorry, but instead of loading equals lazy, let's just go ahead and pull this guy out. If it is set to disable the lazy load, we want it to go ahead and render that same image tag here, but do it without lazy load attribute. Versus otherwise, let's go ahead and make sure that lazy load is included. Let's save, no errors, so far, so good.

I did forget something. In general, let's make this a little bit better. I'm going to scroll down. I'm just now thinking about this for the checkbox. We want to set the default to false. Because, you don't want this to be accidentally saved to true for all images because then that's going to be way harder for people to remember or have to check that for everything. So, let's go ahead and just make sure that that's done. Go ahead and save here and check this off, so far nothing's breaking. Let's take a look at this.

Testing Code

Okey-dokey, you can see I was running some tests in here, and let's just grab this image at first. This is the standard image. We haven't used anything else yet at the moment. You can see here, kind of, in the code that loading equals lazy has been added to this image. It's working as it has been before we added our customizations. Let's come in here though, and let's go ahead and say, "Hey, this is an above the fold image." Let's save. So far so good, nothing's broken. Let's do a refresh on our image here. That felt a little faster. What do you think, did we get rid of that lazy loading attribute and yeah, we did. You can see here that this is going to load in quicker and be a little bit better for that.

If you want to add this to other sections, you're going to follow a similar pattern. One of the ones that I like, if it's just a straight image tag, would be just using an unless tag or whatever wrapped around the lazy loading. That's real simple. Sorry, I was trying to do that in code. Those are some other options that you could take a look at as far as making that a little bit easier. But otherwise, this is a real quick, very simple implementation for you to add. Again, you could make this a little bit more performing using liquid code, but this is the simplest, easiest implementation to get away with to see some really good key performance benefits here.


There you go. Hopefully that was a real quick, short, direct way for you to make some real significant performance benefits on a Shopify store. Real quick and easy win for a performance there without having to do too much code. You can see just a simple checkbox, really easy to understand for merchants as well. I've found that it's very helpful for folks to include and helps give them a little bit more control over that as well. Hopefully, that was helpful to you. Would love to hear about any performance implementations that you've done yourself. Otherwise, I'll probably try to do a couple more of these for ones that I build in the stores regularly here. Because, I think this stuff is helpful. Hopefully, you feel the same. Thanks. 


// Video Resources //

Shopify Dev Docs
Largest Contentful Paint
Lighthouse Scoring Calculator

// General Links //


// Hardware* //

💻 2022 Apple MacBook Pro (16-inch, Apple M1, 32GB RAM, 1TB SSD)
🎙️Rode NT-USB USB Condenser Microphone
⌨️ Keychron K4J2 Mechanical Keyboard
🎧 Bose QuietComfort 45
🪑 MUIGELS Ergonomic Mesh Office Chair

*Some of the items may contain affiliate links and it's possible that I may receive a small commission if you use the link
Back to blog