Test Lazy Loading Images Using Cypress
How to Test Lazy Loading Images Visually Using Cypress
More than 50% of visual regressions on media-heavy pages are linked to content that loads after the initial render.
Lazy loading improves performance, but it also introduces timing gaps where images, components, or entire sections appear later than expected. When Cypress tests capture the page too early, they often miss layout shifts or partially loaded elements that real users eventually see.
Teams already rely on Cypress for automation, but handling lazy-loaded elements correctly requires more than adding arbitrary waits or forced scrolls. The real question is how to ensure your visual tests reflect the fully rendered experience without making tests slow or unstable.
This article explains how lazy loading works in Cypress environments and how to visually test lazy-loaded images with confidence.
What is Lazy Loading in Cypress?
Lazy loading is a technique where images or components load only when they are about to enter the user’s viewport. Instead of rendering everything at once, the browser waits until a user scrolls or interacts with the page.
In applications tested with Cypress, lazy loading usually depends on browser APIs such as Intersection Observer or scroll event listeners. These mechanisms detect when an element becomes visible and then trigger its loading logic. From a testing perspective, this means certain elements may not exist in the DOM or may not be fully rendered when the test first runs.
Cypress executes commands quickly and deterministically. If a test captures the page before lazy-loaded elements appear, the result may not represent the final user experience. This timing gap is where cypress visual testing lazy loading becomes important, because the test must account for dynamic content that loads progressively rather than immediately.
How to Test Lazy Loading Images Visually Using Cypress
Lazy-loaded images rarely fail in a dramatic way. They usually “work,” but load late, render blurry for a moment, or push surrounding content down once they appear. Visual testing helps you catch those subtle issues, but only if Cypress triggers the lazy-loaded assets before taking the screenshot.
A simple approach is to scroll the page so below-the-fold images enter the viewport, then capture a baseline screenshot and compare future runs against it. The BrowserStack guide demonstrates this flow using cy.scrollTo(‘bottom’) before taking the visual snapshot.
Practical workflow
- Visit the page under test.
- Scroll far enough to trigger lazy loading (often the bottom of the page).
- Wait for images to finish loading (avoid fixed waits when possible).
- Capture a visual snapshot and compare against baseline.
Example Cypress test (lazy loading + visual snapshot)
// visual-test.js describe('Cypress Visual Testing Lazy Loading', () => { it('captures lazy-loaded images before snapshot', () => { cy.visit('https://sdk-test.percy.dev/lazy-loading/'); // Trigger below-the-fold lazy loaded assets cy.scrollTo('bottom'); // Take a visual snapshot (plugin command varies by setup) cy.compareSnapshot('lazy-loading'); }); });
A small improvement that keeps tests steadier is to add a lightweight “images are loaded” check before the snapshot. This avoids comparisons against partially loaded placeholders when the network is slower than usual.
cy.get('img').should(($imgs) => { // Ensure images that exist are actually decoded/painted for (const img of $imgs) { expect(img.complete, 'image complete').to.be.true; expect(img.naturalWidth, 'image has width').to.be.greaterThan(0); } });
This section keeps the core idea simple: trigger lazy loading first, then take the visual capture. The next sections dig into why this can still be tricky and how visual testing software like Percy make the workflow more reliable at scale.
Cypress does half the job. Complete your visual accuracy journey with Percy’s visual automation
Challenges With Lazy Loading in Visual Testing
Lazy loading changes when and how content appears, which makes visual testing less predictable. Cypress executes commands quickly, but lazy-loaded elements depend on scrolling, viewport size, and network timing. A screenshot taken too early may capture placeholders instead of final images.
1. Timing and Rendering Delays
Lazy-loaded elements often render asynchronously after scroll events. If the test triggers a scroll and immediately takes a snapshot, images may still be loading in the background.
cy.scrollTo('bottom'); cy.compareSnapshot('lazy-loading'); // Risk: images still loading
This creates flaky visual diffs where one run shows fully loaded images and another shows partial content.
2. Viewport Dependency
Lazy loading relies on elements entering the viewport. Different viewport sizes can change when images load, especially in responsive layouts.
cy.viewport(1280, 800); cy.scrollTo('bottom');
A smaller viewport may require additional scrolling to trigger all lazy-loaded assets, while a larger one may load them sooner. Visual tests must account for this variability.
3. Placeholder and Layout ShiftsMany implementations use low-resolution placeholders or skeleton loaders. Once the actual image loads, it may slightly shift surrounding elements.
Visual comparison tools will detect these layout shifts, but only if the final state is captured consistently. If the snapshot includes intermediate states, your baseline becomes unreliable.
4. Overuse of Static Waits
A common workaround is adding fixed waits:
cy.scrollTo('bottom'); cy.wait(3000); // Not reliable cy.compareSnapshot('lazy-loading');
Static waits slow down test suites and still fail under slow networks. They also make cypress visual testing lazy loading harder to scale across environments.
Visual Testing with Lazy Loading Web Pages Using BrowserStack Percy and Cypress
BrowserStack Percy is an AI-powered visual automation tool designed to detect visual regressions across web and mobile web applications. It supports cross-browser visual testing and renders pages consistently across environments.
Percy integrates with more than 50 frameworks and tools, including Cypress, Selenium, Puppeteer, and WebdriverIO, which makes it easy to plug visual testing into existing automation workflows.
Percy integrates directly with Cypress and captures full-page DOM snapshots instead of simple screenshots. It uploads the DOM and assets, then renders them in a controlled environment for visual comparison. This approach reduces flakiness caused by machine-specific rendering or timing differences.
Install and Configure Percy with Cypress
First, install Percy’s Cypress integration:
npm install --save-dev @percy/cypressThen import Percy commands in your Cypress support file:
// cypress/support/e2e.js import '@percy/cypress';
Example: Lazy Loading + Percy Snapshot
describe('Lazy Loading Visual Test with Percy', () => { it('captures fully loaded lazy content', () => { cy.visit('https://sdk-test.percy.dev/lazy-loading/'); // Trigger lazy loading cy.scrollTo('bottom'); // Ensure images are loaded before snapshot cy.get('img').should(($imgs) => { for (const img of $imgs) { expect(img.complete).to.be.true; expect(img.naturalWidth).to.be.greaterThan(0); } }); // Capture Percy snapshot cy.percySnapshot('Lazy Loading - Fully Rendered'); }); });
Percy captures the DOM after the scroll and image checks complete. It then renders the page across supported browsers and highlights visual differences against the baseline.
This workflow strengthens cypress visual testing lazy loading because snapshots are consistent across environments, layout shifts caused by late-loading elements are clearly detected, and teams can review visual diffs in Percy’s dashboard with side-by-side comparisons.
For mobile applications, App Percy extends similar visual testing capabilities to native and hybrid apps that rely on lazy rendering for performance. The principle remains the same: trigger dynamic content first, then capture the final visual state in a stable environment.
Why Combine Percy With Cypress Visual Testing?
Cypress is excellent for controlling user flows and triggering lazy-loaded content at the right time. Percy strengthens that workflow by adding reliable, scalable visual comparisons across browsers and devices. Together, they create a stable strategy for handling cypress visual testing lazy loading without adding fragile waits or environment-specific hacks.
Below is a breakdown of key Percy capabilities and their impact when combined with Cypress:
| Feature | Description | Impact on Users |
|---|---|---|
| AI-Powered Visual Diffs | The intelligent diff engine highlights meaningful visual changes while reducing noise from minor rendering differences. | Fewer false positives and faster review cycles. |
| Cross-Browser Rendering | Renders snapshots across multiple browser versions in a controlled environment. | Confident releases without manually testing each browser. |
| Full-Page DOM Snapshots | Captures the complete DOM and assets instead of static screenshots. | More accurate representation of lazy-loaded content after scroll triggers. |
| Mobile Web Visual Testing | Tests responsive layouts across mobile browsers and viewport sizes. | Detects layout shifts caused by lazy loading on smaller screens. |
| Native App Visual Testing | App Percy extends visual testing to native and hybrid mobile apps. | Ensures visual consistency in apps that use lazy rendering patterns. |
| 50+ Framework Integrations | Integrates with Cypress, Selenium, Puppeteer, WebdriverIO, and more. | Easy adoption without changing existing automation stacks. |
| Parallel Test Execution | Runs visual tests alongside functional tests in CI pipelines. | Faster feedback without slowing down release cycles. |
| Centralized Review Dashboard | Side-by-side baseline comparisons with team collaboration features. | Clear visibility into regressions before merging code. |
| CI/CD Integration | Connects with popular CI tools to block merges on visual changes. | Prevents unintended UI regressions from reaching production. |
Thinking about maximizing visual automation?
Percy introduces best-in-class AI-powered visual automation to scale across multiple branches, picking UI regressions 3x faster.
Pros & Cons of Lazy Loading in Cypress Visual Testing
Lazy loading improves performance, but it changes how and when UI elements appear. When combined with visual testing in Cypress, it introduces both advantages and trade-offs. Understanding both sides helps teams design more reliable test strategies.
Pros:
- Improved Page Performance: Lazy loading reduces initial page weight by loading images and components only when needed. Faster load times mean quicker test execution in many scenarios. This also mirrors real user behavior more closely, especially on content-heavy pages.
- Better Resource Utilization: Since assets load progressively, network usage is distributed rather than spiking at page load. Visual tests that scroll intentionally can control when assets load, making test behavior more predictable when structured correctly.
- Closer Alignment With Real User Flows: Most users scroll through pages gradually, triggering content as they move. Testing lazy loading within Cypress simulates realistic interaction patterns rather than artificial full-page rendering.
- Scalable for Large Applications: Applications with long feeds or media galleries benefit significantly from lazy loading. When paired with structured visual testing, teams can focus snapshots on meaningful states instead of loading unnecessary content upfront.
- Works Well With Screenshot-Based Tools: When dynamic content is properly triggered before capture, tools like Percy handle visual comparison reliably. This ensures layout shifts or delayed renders are detected once the final state is stabilized.
Cons:
- Timing-Related Flakiness: Lazy-loaded elements depend on scroll events and rendering delays. If snapshots are captured too early, visual diffs may show placeholders or partially loaded images.
- Viewport Sensitivity: Different screen sizes trigger lazy loading at different scroll positions. Tests must carefully control viewport dimensions to maintain consistency across runs.
- Increased Test Complexity: Additional logic is often required to scroll, verify image loading, or wait for rendering to complete. This adds maintenance overhead compared to testing fully rendered static pages.
- Risk of Overusing Static Waits: Teams sometimes rely on fixed delays to stabilize tests. These waits slow down pipelines and still fail under inconsistent network conditions.
- Hidden Edge Cases in Responsive Layouts: Lazy loading combined with responsive design can introduce subtle layout shifts. Without structured visual testing, these issues may go unnoticed until production.
30% UI Regressions Are Still Missed Without The Right Tool
Conclusion
Lazy loading improves performance, but it changes how visual states appear during automated tests. Without a structured approach, Cypress may capture incomplete renders or miss subtle layout shifts. Handling cypress visual testing lazy loading requires intentional scrolling, stable rendering checks, and controlled snapshot timing.
Combining Cypress with a visual automation tool like Percy strengthens this workflow. Cypress manages user flows and triggers dynamic content, while Percy ensures consistent cross-browser visual comparison. Together, they help teams release faster without overlooking regressions caused by lazy-loaded elements.
Related Articles
What is Visual Testing [A 2026 Guide]
Many visual bugs slip past automation. Visual testing adds a safety net by comparing how your websit...
A Complete Guide to Visual UI Testing in 2026
Visual UI testing detects visual changes across screens and devices. This guide covers how it works ...
What is Visual Regression Testing [2026]
Visual regression testing detects unintended UI changes by comparing visual baselines. This article ...
