Configure Swiper Lazy Loading to Load Images on Demand
Learn how to enable Swiper’s Lazy Loading module to defer image loads, reduce initial bandwidth, and avoid common setup mistakes.
23 Sept 2025, 16:04 UTC

Problem: unnecessary image loads waste bandwidth
When a Swiper contains many slides with large images, loading every image at page‑load increases initial data transfer and can delay the first meaningful paint.
Useful takeaway: enable Swiper’s Lazy Loading module so images are fetched only when a slide enters or nears the viewport, reducing bandwidth and improving perceived performance.
Worked configuration
The following example shows a minimal Swiper that loads the current slide, the previous slide, and the next slide immediately, while all other slides wait until they are about to be shown.
<!-- Swiper container -->
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img class="swiper-lazy" data-src="https://example.com/image1.jpg" alt="">
<div class="swiper-lazy-preloader"></div>
</div>
<div class="swiper-slide">
<img class="swiper-lazy" data-src="https://example.com/image2.jpg" alt="">
<div class="swiper-lazy-preloader"></div>
</div>
<!-- repeat for as many slides as needed -->
</div>
</div>
import Swiper from 'swiper';
import { Lazy } from 'swiper/modules';
// Initialize Swiper with the Lazy module
const swiper = new Swiper('.mySwiper', {
modules: [Lazy],
lazy: {
loadPrevNext: true, // load adjacent slides
loadPrevNextAmount: 2, // load two slides before and after the active one
loadOnTransitionStart: true // start loading as soon as the transition begins
},
// optional: enable pagination, navigation, etc.
pagination: { el: '.swiper-pagination' },
navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' }
});
Key points in the markup:
- Each image uses
class="swiper-lazy"and stores its URL indata-src(ordata-srcsetfor responsive sources). The regularsrcattribute is omitted. - The optional
<div class="swiper-lazy-preloader"></div>provides a visual cue while the image loads; Swiper removes it automatically once the image arrives.
The lazy object configures three behaviors:
loadPrevNext: truetriggers preloading of adjacent slides.loadPrevNextAmount: 2loads the two slides before and after the active one (current + previous + next).loadOnTransitionStart: truestarts loading as soon as the slide transition begins, avoiding a flash of empty space.
How the mechanism works
When Swiper initializes, it registers the Lazy module. During each slide change, Swiper checks the visibility of slides using the browser’s IntersectionObserver (or a fallback scroll‑position check on older browsers). If a slide’s image element carries the swiper-lazy class and a data-src attribute, Swiper creates an img node, sets its src to the value from data-src, and inserts it into the slide, simultaneously removing the preloader element. Images that are not yet near the viewport remain untouched, keeping their data-src unchanged and preventing network requests.
Limits and common mistakes
- Missing class or attribute – If an image lacks
swiper-lazyordata-src, Swiper ignores it and the slide shows a blank area. - Variable slide height – Lazy loading relies on the slide’s dimensions to decide if it is in the viewport. If the slide’s container height is not set (e.g.,
height: autowith content‑driven sizing), Swiper may never consider the slide visible, and the image will not load until a manual resize triggers a re‑check. - Disabled adjacent preloading – Setting
loadPrevNextAmount: 0turns off preloading of neighboring slides. When a user swipes quickly, the next slide may still be loading, causing a visible delay or a flash of the preloader. - Server‑side rendering (SSR) – In environments where the page is rendered on the server, images may be fetched during the initial HTML generation, defeating the purpose of lazy loading. To avoid this, ensure the Lazy module is only instantiated on the client (e.g., wrap Swiper initialization in a
useEffector checktypeof window !== 'undefined'). - Conflicting observer settings – Enabling
observer: trueorwatchSlidesProgress: truecan interfere with the lazy module’s internal observers if not used carefully. Test that images still load when these flags are active. - Old browsers without IntersectionObserver – Swiper falls back to a scroll‑position check, which is less precise and may trigger eager loading in some edge cases. If you need to support IE11, consider a polyfill or accept that lazy loading will be less effective.
Verifying the behavior
- Open the page with the Swiper instance.
- Open DevTools → Network panel and enable “Disable cache” to see fresh requests.
- Notice that only the image for the initially active slide (and, with the example config, the previous and next slides) appears in the network list immediately.
- Swipe or click to move to a new slide. Observe a new request for that slide’s image appear, and the preloader element show until the request finishes.
- Repeat the test with mobile device emulation or a throttled connection (e.g., “Fast 3G”) to see the bandwidth savings.
- To verify that adjacent preloading is disabled, set
loadPrevNextAmount: 0and repeat the swipe test; you should see no requests for slides until they become the active one.
If any of the expected requests are missing, double‑check the markup for the swiper-lazy class and data-src attribute, ensure the slide container has a defined height, and confirm that the Lazy module is included in the modules array.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.