Get Your Free Proposal Now!

SEO Knowledge Base

What Is Lazy Loading? How to Implement It?

Muhammad Saad Published: Sep 23, 2026 14 min. read Summarize in ChatGPT

Lazy loading is a loading technique that delays images, videos, application code, routes, database records or other resources until the resources are actually needed. Examples include below-the-fold images, videos, React components, Angular routes and database relationships. Lazy loading can reduce initial downloads, network requests and processing, but incorrect implementation can delay important content, create extra database queries and cause SEO problems. Implementation for images, videos, React, JavaScript, Angular, C#, databases and Python, differences from eager loading and skeleton loading, advantages, disadvantages, browser-level loading, use cases, best practices, methods and SEO are explained below.

What Is Lazy Loading?

Lazy loading is a performance technique that delays the loading or initialization of a resource until the resource is needed by the user, application or program.

For example, an image located near the bottom of a webpage does not need to download when the user first opens the page. Lazy loading allows the browser to wait until the user approaches the image before requesting it. lazy loading as a strategy for identifying non-critical resources and loading the resources only when needed.

What Are Examples of Lazy Loading?

Examples of lazy loading are below-the-fold images, embedded videos, YouTube iframes, React components, Angular routes, JavaScript modules, infinite-scroll content, database relationships and Python properties.

  1. Images: Product images near the bottom of an ecommerce page load when the visitor scrolls toward them.
  2. Videos: A video file waits until playback or until the video approaches the viewport.
  3. Iframes: An embedded map or YouTube player loads near the time the visitor reaches it.
  4. React Components: A large dashboard component downloads only when React needs to render the component.
  5. Angular Routes: An admin section downloads when the user opens the /admin route.
  6. JavaScript Modules: import() downloads a JavaScript module only when application logic requests the module.
  7. Database Relationships: An ORM retrieves related records when a relationship property is accessed.
  8. Python Objects: An expensive value can be created during its first property access instead of during object creation.

How Does Lazy Loading Images Work?

Lazy loading images works by delaying the network request for an off-screen image until the browser determines that the image is close enough to the visible viewport.

The normal browser method uses loading="lazy":

<img
  src="product.jpg"
  loading="lazy"
  width="800"
  height="600"
  alt="Product image">

The loading process is:

  1. The browser reads the HTML. The browser finds an image marked with loading="lazy".
  2. The browser checks its position. An image far outside the viewport does not need to download immediately.
  3. The user scrolls toward the image. The image reaches a browser-calculated distance from the viewport.
  4. The browser requests the image. The file begins downloading before or around the time the image becomes visible.
  5. The browser displays the image. The specified width and height reserve its layout space while loading.

Why Is Lazy Loading Important?

Lazy loading is important because modern webpages can contain many images, JavaScript files, videos and other resources that users may never view during a visit. Delaying non-critical resources reduces unnecessary initial network and processing work.

HTTP Archive reported that the median desktop webpage transferred about 3,015.5 KB and the median mobile webpage about 2,627.9 KB in August 2026. The same dataset reported a median of 19 image requests on desktop and 16 on mobile.

Image weight also explains why image lazy loading matters. The HTTP Archive Web Almanac found that the median desktop homepage transferred about 1,054 KB of images and the median mobile homepage about 900 KB in its 2024 dataset. At the 90th percentile, image weight reached about 6,526 KB on desktop and 5,905 KB on mobile.

How to Implement Lazy Loading?

To implement lazy loading, identify resources that are not required during the initial screen, select a loading trigger, delay the resource, provide a temporary state where necessary and test the result.

  1. Identify non-critical resources. Select below-the-fold images, videos, secondary routes, optional components or related database data.
  2. Select the trigger. Common triggers are viewport proximity, route navigation, property access, button click or component rendering.
  3. Delay the resource. Use native HTML attributes, Intersection Observer, dynamic imports, framework routing or ORM settings.
  4. Reserve the required space. Images and videos should have dimensions or suitable placeholders to prevent layout movement.
  5. Load before the user needs the resource. Loading too late can create visible delays.
  6. Test performance and behavior. Check network requests, Core Web Vitals, rendered HTML and database query counts.

How to Implement Lazy Loading for Images?

Lazy loading for images can be implemented by adding loading="lazy" to images that are expected to start outside the initial viewport.

<img
  src="gallery-08.webp"
  loading="lazy"
  width="900"
  height="600"
  alt="Gallery image">

Browser-level lazy loading requires no separate JavaScript library. Keep hero images and other likely LCP images eager, and add width and height so browser layout space exists before the image arrives.

How to Implement Lazy Loading in Video?

Lazy loading in video can be implemented with preload="none" so the browser does not preload the video data before playback. A poster image can display a preview while the video waits.

<video controls preload="none" poster="preview.webp" width="800" height="450">
  <source src="video.mp4" type="video/mp4">
</video>

Newer browser implementations also support or are introducing loading="lazy" for media elements, but support is not as universal as image lazy loading. preload="none" remains useful when playback depends on the user. web.dev recommends avoiding lazy loading when the video or its poster is the page’s LCP element.

How to Implement Lazy Loading in React?

Lazy loading in React can be implemented with lazy() and <Suspense>. React downloads the component code when the component is first required for rendering.

import { lazy, Suspense } from 'react';

const Reports = lazy(() => import('./Reports.jsx'));

function App() {
  return (
    <Suspense fallback={<p>Loading...</p>}>
      <Reports />
    </Suspense>
  );
}

lazy() uses dynamic import() and expects the imported component to be available as a default export. <Suspense> displays fallback content while the component code loads.

How to Implement Lazy Loading in JavaScript?

Lazy loading in JavaScript can be implemented with the Intersection Observer API. Intersection Observer watches an element and runs loading code when the element approaches or enters the viewport.

<img class="lazy" data-src="photo.webp" width="800" height="600" alt="Photo">
const images = document.querySelectorAll('.lazy');

const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (!entry.isIntersecting) return;

    const image = entry.target;
    image.src = image.dataset.src;
    observer.unobserve(image);
  });
});

images.forEach(image => observer.observe(image));

Intersection Observer avoids continuously checking the scroll position manually. MDN lists Intersection Observer as a standard method for implementing custom lazy loading.

How to Implement Lazy Loading in Angular?

Lazy loading in Angular can be implemented with loadComponent for a component or loadChildren for child routes.

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: 'reports',
    loadComponent: () => import('./reports/reports.component')
  },
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.routes')
  }
];

Angular compiles lazy-loaded application sections into separate JavaScript chunks. The router requests the required chunk when the corresponding route becomes active. Angular recommends eager loading for primary landing pages and lazy loading for other routes when separating the code improves initial loading.

How to Implement Lazy Loading in C#?

Lazy loading in C# database applications can be implemented with Entity Framework Core lazy-loading proxies. Install Microsoft.EntityFrameworkCore.Proxies, enable UseLazyLoadingProxies() and make navigation properties eligible for proxy overriding.

optionsBuilder
    .UseLazyLoadingProxies()
    .UseSqlServer(connectionString);
public class Blog
{
    public int Id { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

EF Core loads the related Posts data when the navigation property is accessed. Microsoft warns that lazy loading can generate unnecessary database round trips and produce the N+1 query problem.

How to Implement Lazy Loading in Database?

Lazy loading in a database is commonly implemented through an Object-Relational Mapper (ORM). The initial query retrieves the main records and leaves related records unloaded. Accessing a related property triggers another query.

For example:

Load 100 Customers → Access Customer.Orders → Load Orders when each relationship is needed

SQLAlchemy describes lazy relationship loading as returning the main object first and issuing another SELECT when the related collection or reference is first accessed. Lazy loading can save unnecessary data retrieval, but repeatedly accessing lazy relationships can create the N+1 problem. Loading 100 parent records with 1 initial query and then issuing 100 separate relationship queries can produce 101 queries.

How to Implement Lazy Loading in Python?

Lazy loading in Python can be implemented by delaying an expensive operation until the related property is first accessed. Python’s functools.cached_property is useful when the value should be calculated or loaded once and then stored.

from functools import cached_property

class Product:
    @cached_property
    def reviews(self):
        return load_reviews_from_database()

reviews is not loaded when the Product object is created. Python evaluates the method during the first product.reviews access and stores the resulting value for later accesses. Python documentation describes cached_property as a property whose value is computed once and then cached for the life of the instance.

What Is the Difference Between Lazy Loading and Eager Loading?

The difference between lazy loading and eager loading is when a resource is loaded. Lazy loading waits until the resource is needed, while eager loading loads the resource during the initial operation. Lazy loading can reduce initial data transfer and processing, while eager loading can remove the later delay required to retrieve the resource.

Feature Lazy Loading Eager Loading
Loading time Loads when needed Loads immediately
Initial request Smaller in many use cases Larger in many use cases
Initial speed Can be faster Can be slower when much unused data is loaded
Later access May require waiting Resource is already available
Bandwidth Avoids some unused downloads May download unused resources
Web example Below-the-fold image loads near viewport Hero image loads immediately
Application example Component downloads when rendered Component included in initial bundle
Database example Related rows load when property is accessed Related rows load with initial query
Main risk Too many later requests Too much initial loading
Best use Optional or non-critical resources Immediately required resources

What Is the Difference Between Lazy Loading and Skeleton Loading?

The difference between lazy loading and skeleton loading is their purpose. Lazy loading controls when the real resource is requested or initialized, while skeleton loading controls what the user sees while real content is loading. Both techniques can be used together: lazy loading can delay a component, and a skeleton can occupy the component area during its later network request.

Feature Lazy Loading Skeleton Loading
Main purpose Delay unnecessary loading Show temporary visual structure
Performance technique Yes Primarily a perceived-loading UI technique
Controls network request Can Usually no
Controls user interface Indirectly Yes
Display Real content appears after trigger Placeholder appears before real content
Example Product image starts downloading near viewport Gray product-card shape appears while data loads
Can work together Yes Yes

What Are the Advantages of Lazy Loading?

The advantages of lazy loading are lower initial data transfer, fewer unnecessary initial requests, smaller initial JavaScript bundles, reduced initial processing, lower memory use in some applications and faster loading of important content when lazy loading is applied only to non-critical resources. The benefit depends on selecting the correct resources.

  1. Reduces initial downloads: Off-screen images, videos and secondary application code do not need to download immediately.
  2. Saves bandwidth: Resources that the user never reaches may never need to download.
  3. Reduces initial JavaScript: Code splitting can keep secondary application code outside the initial JavaScript bundle.
  4. Reduces initial processing: Browsers and applications have fewer resources to parse, decode or initialize at startup.
  5. Supports large pages: Long product pages, image galleries and feeds can load resources progressively.
  6. Can reduce database work: Related database records do not need to be retrieved when application code never accesses the relationship.
  7. Can improve initial performance: Network bandwidth and processing remain available for resources required on the first screen.

What Are the Disadvantages of Lazy Loading?

The disadvantages of lazy loading are delayed access to deferred resources, extra network requests, possible SEO problems, possible LCP delays, layout movement from improperly sized media, database N+1 queries and additional implementation complexity. Microsoft specifically warns about unnecessary round trips from database lazy loading, while Google warns that incorrectly implemented lazy loading can hide content from Google Search.

  1. Creates later loading delays: A user can reach a resource before the resource finishes downloading.
  2. Can hurt LCP: Lazy loading a hero or LCP image delays an important visible resource.
  3. Can cause SEO problems: Content that requires scrolling, clicking or unsupported JavaScript behavior may not be available to a crawler.
  4. Can create layout shift: Images without reserved dimensions can change page layout when the image appears.
  5. Can increase request count: Deferred components or database relationships can create many later requests.
  6. Can create N+1 database queries: Accessing a lazy relationship for many records can produce one extra query for each record.
  7. Adds implementation decisions: Developers must decide what should load immediately, what should wait and what loading trigger should be used.

What Is Browser-Level Lazy Loading?

Browser-level lazy loading is native lazy loading controlled by the browser through HTML attributes such as loading="lazy", mainly for images and iframes, without requiring a custom JavaScript lazy-loading library.

When to Use Lazy Loading?

Use lazy loading for resources that are expensive and not required during the initial user experience, such as below-the-fold images, secondary videos, embedded iframes, optional application components, secondary routes and database relationships that are not always accessed. Do not normally lazy-load the page’s hero image, LCP resource, primary navigation code or other content required immediately after opening the page. Google also recommends avoiding lazy loading for content likely to be immediately visible when the page opens.

What Are the Lazy Loading Best Practices?

Lazy loading best practices are loading only non-critical resources lazily, keeping LCP resources eager, reserving media dimensions, loading resources shortly before use, providing fallbacks, avoiding excessive database queries and testing both performance and search-engine rendering.

  1. Lazy-load below-the-fold resources: Apply lazy loading where initial visibility is unlikely.
  2. Do not lazy-load LCP resources: Hero images and other primary LCP elements should start downloading early.
  3. Add image and video dimensions: Set width and height or reserve equivalent aspect-ratio space.
  4. Use native loading where practical: loading="lazy" is simpler than custom JavaScript for supported resources.
  5. Use Intersection Observer for custom behavior: Intersection Observer is suitable when loading requires custom viewport thresholds or data-source swapping.
  6. Load slightly before visibility: Starting the request before the element becomes visible reduces the chance that users see an empty area.
  7. Monitor database queries: Replace problematic lazy relationships with eager or batched loading when lazy loading creates N+1 queries.
  8. Keep important content crawlable: Lazy-loaded content should appear when visible without requiring a click or scrolling action from Googlebot.
  9. Test rendered HTML: Google recommends checking the rendered HTML through URL Inspection to confirm lazy-loaded content and media URLs are available.
  10. Measure instead of applying lazy loading everywhere: Compare network requests, bundle sizes, LCP, CLS and database query counts before and after implementation.

How Many Methods Are There to Implement Lazy Loading?

There is no official fixed number of lazy-loading methods because lazy loading is a strategy rather than one API. In practical web and application development, 6 common implementation methods cover most uses: native browser lazy loading, Intersection Observer, dynamic imports and code splitting, route-based lazy loading, event-based loading and data or ORM lazy loading.

The 6 common methods to implement lazy loading are:

  1. Native Browser Lazy Loading
  2. Intersection Observer Lazy Loading
  3. Dynamic Import and Code-Splitting Lazy Loading
  4. Route-Based Lazy Loading
  5. Event-Based or On-Demand Lazy Loading
  6. Database and ORM Lazy Loading

1. Native Browser Lazy Loading

Native browser lazy loading uses built-in browser behavior instead of custom JavaScript. Images and iframes can use the loading="lazy" attribute.

<img src="photo.webp" loading="lazy" alt="Photo">

The browser decides when the resource is close enough to the viewport to begin loading. Native loading is normally the simplest method for ordinary off-screen images and iframes.

2. Intersection Observer Lazy Loading

Intersection Observer lazy loading uses JavaScript to observe whether an element is entering or approaching the viewport.

The developer can replace data-src with src, request API data, initialize a map or start another loading operation when the observer fires. Intersection Observer provides more control than the basic loading="lazy" attribute.

3. Dynamic Import and Code-Splitting Lazy Loading

Dynamic import lazy loading separates JavaScript into smaller chunks and downloads a chunk only when application code requests the chunk.

const module = await import('./analytics.js');

React’s lazy() uses dynamic import() for lazy component loading. Code splitting is useful when a large feature does not need to be included in the initial application bundle.

4. Route-Based Lazy Loading

Route-based lazy loading divides an application according to pages or routes. Code belonging to /admin, /reports or another secondary route loads when the user visits that route.

Angular provides loadComponent and loadChildren for this approach. Lazy routes compile into separate JavaScript chunks requested when the matching route is opened.

5. Event-Based or On-Demand Lazy Loading

Event-based lazy loading starts a resource after a specific user or application event. Common triggers include clicking a tab, expanding an accordion, opening a modal, hovering over an element or pressing a play button.

For example, a website can avoid loading an interactive map until a visitor opens the “View Map” panel. Event-based loading is useful when the resource has a low probability of being used during every visit.

6. Database and ORM Lazy Loading

Database lazy loading retrieves related data only when application code accesses the relationship. ORMs such as EF Core and SQLAlchemy support forms of relationship lazy loading.

The method can avoid loading unused rows, but database query counts must be monitored because repeated lazy relationship access can create N+1 queries. SQLAlchemy describes lazy loading as issuing a SELECT at attribute-access time, while EF Core warns that the same pattern can create unnecessary database round trips.

Is Lazy Loading Good or Bad for SEO?

Lazy loading is good for SEO when non-critical content loads automatically when visible and important/LCP content remains eager; incorrect lazy loading can hide crawlable content or delay important page content.

About the Author

Muhammad Saad

SEO Specialist

I am an SEO specialist with 2+ years of experience helping brands grow organic visibility. I have worked with multiple clients, built and optimized websites across niches, and run a YouTube channel where I teach Semantic SEO with practical strategies you can apply.

Write a comment

Your email address will not be published. Required fields are marked *

SEO solutions for businesses of every size. More visibility. More traffic. More leads.

© 2026 UppLead SEO. All Rights Reserved.

Date
Time
Details
Done

Choose a Date

Select a day that works best for your free consultation call

March 2026

SunMonTueWedThuFriSat
Timezone: Auto-detected

Pick a Time

Available time slots for

Morning

Afternoon

Evening

Your Details

Tell us a bit about yourself so we can prepare for your call

You're All Set!

Your free call has been booked successfully

Date
Time
Duration 30 minutes