Claude Code can add lazy loading to images across your entire codebase in minutes, not hours. It works by scanning your HTML, JSX, or framework templates, identifying images missing the `loading="lazy"` attribute or an intersection observer, and applying fixes automatically. This guide is for developers who want to improve page performance without breaking focus on their main task.

- Lazy loading images can reduce initial page load weight by **20-50%** depending on image density ( [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading))
- The native `loading="lazy"` attribute is supported in **all modern browsers** with 96%+ global coverage
- Claude Code can process an entire components directory in a single prompt, making codebase-wide refactors fast

## What is lazy loading and why does it matter for performance?

Lazy loading defers the loading of images until they are about to enter the viewport. Instead of downloading every image on page load, the browser only fetches what the user is actually about to see. The result is faster Time to First Contentful Paint (FCP) and lower bandwidth usage, both of which directly affect [Core Web Vitals scores](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/) and SEO ranking.

There are two main approaches:

- **Native lazy loading**: Add `loading="lazy"` to `<img>` tags. Simple, zero-dependency, widely supported.
- **Intersection Observer API**: A JavaScript-based approach for custom behavior, useful for background images or components that the native attribute cannot cover.

Claude Code handles both. You tell it which approach you want and it applies the pattern consistently, even across large projects.

## How to prompt Claude Code to add native lazy loading

The simplest and most impactful change is adding `loading="lazy"` to every image that is not above the fold. Open a Claude Code session in your project root and use a prompt like this:

### Prompt for HTML/JSX projects

```
Find all <img> tags in the src/ directory that do not have loading="lazy".
Add loading="lazy" to each one. Skip any images inside <header> or
with a class containing "hero" or "above-fold", since those should load eagerly.
```

Claude Code will search through your files, identify the relevant tags, and apply the attribute. It respects your constraint about above-the-fold images, which is important because lazy loading your hero image will actually _hurt_ your LCP score.

### Prompt for Next.js or React projects using a custom Image component

```
In our Next.js project, all images use the next/image component.
Review every usage in src/components/ and src/pages/ and confirm that
images below the fold have priority={false}. Flag any that have
priority={true} unnecessarily. Suggest fixes.
```

If you are using [Next.js Image](https://nextjs.org/docs/pages/api-reference/components/image), the `priority` prop controls eager vs. lazy loading. Claude Code understands framework-specific conventions and will apply the right pattern.

## How to use Claude Code to implement Intersection Observer lazy loading

For background images, custom carousels, or components that cannot use the native attribute, the Intersection Observer API is the right tool. Here is a prompt that works well:

```
Create a reusable useLazyLoad React hook using IntersectionObserver.
It should accept a ref and return a boolean `isVisible`.
Then refactor the ProductCard component in src/components/ProductCard.jsx
to use this hook so the product image only loads when the card is near the viewport.
```

Claude Code will generate the hook, wire it into the component, and handle the `src` swap (from a placeholder to the real URL) when the element becomes visible. You can then ask it to apply the same hook to other components by name.

### Handling background images in CSS

Background images set via CSS cannot use `loading="lazy"`. Use this prompt to address them:

```
Find all components that set a background image inline via style props or
CSS-in-JS. Refactor them to use an IntersectionObserver pattern so the
background image URL is only applied when the element is 20% visible.
```

## Key takeaways for lazy loading images with Claude Code

1. **Start with a scoped prompt**: Target one directory or component type at a time to keep diffs reviewable.
2. **Exclude above-the-fold images explicitly**: Mention hero images, header logos, and any image with an LCP role in your prompt.
3. **Specify your framework**: Tell Claude Code whether you are using vanilla HTML, Next.js, Astro, or another framework so it applies the idiomatic pattern.
4. **Ask for a summary before applying**: Prompt Claude Code to list affected files first. Review, then ask it to apply changes. This prevents unexpected rewrites.
5. **Validate with Lighthouse**: After Claude Code applies the changes, run a [Lighthouse audit](https://developer.chrome.com/docs/lighthouse/overview/) to confirm the improvement in your performance score.

## Common lazy loading mistakes Claude Code can help you fix

| Mistake | Impact | How Claude Code fixes it |
| --- | --- | --- |
| Lazy loading the hero/LCP image | LCP score gets worse | Detects hero patterns and excludes them from changes |
| No explicit width/height on lazy images | Cumulative Layout Shift (CLS) | Adds `width` and `height` attributes alongside `loading="lazy"` |
| Lazy loading images inside `<picture>` without updating the `<img>` fallback | Inconsistent behavior across browsers | Updates both the source set and the fallback `<img>` tag |
| Using a placeholder `src` that triggers a 404 | Console errors, broken UI before intersection | Suggests a proper 1x1 transparent placeholder or `data:` URI |
