ScreenshotNeo

BlogHow-to

Chrome DevTools Full-Page Screenshot of a Lazy-Loaded Page: Limitations and Fixes

Chrome DevTools can capture beyond the viewport, but that does not guarantee lazy-loaded content has rendered. Learn how to diagnose missing content and capture it reliably.

By the ScreenshotNeo team4 October 20268 min read

Short answer: Chrome DevTools Device Mode’s Capture a full size screenshot captures page area beyond the visible viewport, but it is not documented to scroll the page or trigger every custom lazy-loading handler. If the page loads content only when it approaches the viewport, scroll through it in steps, wait for loading and rendering, then capture and inspect the result.

The key distinction is between capture extent (how much page area the screenshot includes) and page state (which images and dynamic content have actually loaded). Expanding the screenshot does not necessarily change the page state.

Capture a full-size screenshot in DevTools

  1. Open the page in Chrome and open DevTools.
  2. Turn on Device Mode with the device toolbar toggle.
  3. Open the Device Mode More options menu.
  4. Select Capture a full size screenshot. Use Capture screenshot if you only need the visible viewport.
  5. Open the saved image and check the sections and images that matter. A full-page image can still contain placeholders or blank areas if the page had not loaded them.

Chrome documents the full-size option as capturing the whole page, including content that is not currently visible in the viewport. That describes the screenshot area, not a promise to simulate a visitor scrolling down the page. Chrome DevTools: Simulate mobile devices with Device Mode.

Why is my Chrome full-page screenshot missing images?

First identify how the page loads the missing content. Common mechanisms behave differently:

Mechanism What it does What to try
Native loading="lazy" The browser defers offscreen images until they approach a browser-calculated distance from the viewport. The distance is heuristic and can vary with conditions and browser versions. Scroll the image into view, wait for it to load, and verify it in the final capture. If you own the page, avoid lazy-loading images likely to be visible immediately.
IntersectionObserver Site JavaScript may load or reveal content when an element approaches or enters the viewport. Scroll far enough to cross the site’s observation threshold, then wait for the callback and resulting requests to finish.
Scroll handler Custom code may react to scroll events, sometimes only after a particular position or direction. Scroll in increments through the page and watch for newly added content. A single jump to the bottom may not reproduce the expected sequence.
Infinite scroll The page fetches another chunk as you reach the end of the content already loaded. Trigger each chunk, wait for it, and capture the resulting states. For reproducible coverage, use paginated chunks with stable URLs when available.
Layout shift or zero-size images Images without reserved dimensions can change layout as they load. A gallery with zero-size images can also affect which images the browser initially considers near the viewport. When you control the page, provide image width and height or an aspect ratio so space is reserved before image data arrives.

Browser-level lazy loading uses heuristics, not a fixed screenshot threshold you can rely on. Historical Chrome threshold values documented for 2020 are implementation history, not current settings to hard-code. Chrome: Browser-level image lazy loading.

Does “Capture a full size screenshot” trigger lazy loading?

It requests a screenshot that extends beyond the visible viewport. The documentation does not say that this command scrolls through the page to fire arbitrary site-specific scroll handlers. Native lazy loading, an observer, and a custom scroll listener are page-loading behaviors; screenshot geometry is a separate concern.

Google recommends that relevant lazy-loaded content load when it becomes visible, without requiring a user action such as clicking or scrolling, and advises against lazy-loading content likely to be immediately visible. This is useful guidance for page owners and a clue when diagnosing pages you do not control. Google Search Central: Fix lazy-loaded content.

How to capture custom scroll-loaded content

  1. Record what is missing. Note the approximate section or image positions in the output, then inspect the page at those positions.
  2. Scroll incrementally. Move down enough for the next content section to approach or enter the viewport. Repeat through the page so visibility observers and scroll handlers get a chance to run.
  3. Wait for the page to settle. Allow requests and rendering to finish after each step. Look for image placeholders becoming images and for new content appearing below the current end.
  4. Repeat for every infinite-scroll chunk. Reaching the bottom once may add another chunk and move the bottom. Continue until the expected content is present, or use the site’s paginated URLs.
  5. Capture the full page. Use DevTools’ full-size screenshot option after loading the content you need.
  6. Verify the artifact. Inspect the saved image at the expected sections. If a section is still blank, return to that position, determine whether it has loaded, and capture again.

This scroll-and-wait workflow is an operational workaround based on visibility-driven loading, not a Chrome guarantee. Network quiet alone may not prove that delayed timers, animations, or application state have finished.

For infinite-scroll content, a single screenshot should not be treated as proof that every chunk was reached. Google’s guidance recommends persistent unique URLs for chunks, sequential links, and updating the displayed URL as a user moves to a new chunk. If the site offers those URLs, capturing each one is easier to repeat and verify.

Fix lazy loading when you own the page

  • Load relevant content on visibility. Do not make important content depend on a click or other user gesture before it can load.
  • Keep likely above-the-fold images eager. Lazy loading an image that is already likely to be visible can delay its appearance. Setting loading="eager" removes lazy deferral for that image, but does not by itself give it higher priority than other resources.
  • Set dimensions. Provide width and height, or equivalent aspect-ratio styling, so the browser reserves layout space and image loading is less likely to shift content.
  • Make dynamic chunks addressable. For long lists, provide stable URLs and sequential navigation where practical. This helps users and makes captures repeatable.
  • Test the actual output. Check both page behavior and the resulting screenshot at the viewport and device settings you intend to use.

If an important image should be fetched with higher priority, Chrome’s guidance treats fetch priority as a separate consideration from setting loading="eager". Do not assume eager loading alone prioritizes it. See the Chrome lazy-loading guidance.

Automating with the Chrome DevTools Protocol

The DevTools Protocol’s Page.captureScreenshot includes captureBeyondViewport, which controls whether capture can extend beyond the viewport. It controls screenshot extent; it does not substitute for a plan to trigger page loading. For a custom-loaded page, make the content load first, then capture it.

{
  "method": "Page.captureScreenshot",
  "params": {
    "format": "png",
    "captureBeyondViewport": true
  }
}

This is the protocol method and parameter shape, not a standalone command-line program. A client must establish a DevTools Protocol session, enable or navigate the page as needed, trigger and wait for the content, issue the command, and save the returned image data. See the Chrome DevTools Protocol Page domain reference for current parameters and response details.

Common problems and fixes

Symptom Likely cause Fix
Bottom section is blank in the image Its content is activated by visibility or a scroll event that never ran. Scroll down in increments, wait for content, then capture again.
Some images show placeholders Image requests have not started or finished, or rendering has not completed. Bring the images into view, wait, and inspect the saved result. Check whether the site has an error or blocked image request.
Only the first set of items appears The page uses infinite scroll and additional chunks were never requested. Trigger and wait for each chunk, or capture the site’s paginated URLs individually.
Later sections shift or overlap Images or embeds changed size after layout was captured or inspected. Wait for the layout to settle; if you own the page, reserve image space with dimensions or an aspect ratio.
Scrolling once to the bottom does not load everything The site expects successive visibility events or loads one chunk at a time. Scroll through in smaller steps and verify each newly added section.
The full-size option is unavailable or the capture is the wrong size Device Mode may not be active, or the viewport and page layout are not the intended capture setup. Enable the device toolbar, check the selected viewport, and use the full-size menu option rather than the viewport-only screenshot.

Performance, reliability, and cost

Incremental scrolling adds time because each step may trigger network requests, JavaScript, image decoding, and layout work. Wait only as long as the page needs to reveal the content, and verify the result rather than repeating captures blindly. For long or infinite pages, splitting work by stable paginated URLs makes failures easier to isolate and captures easier to reproduce.

For a one-off capture, DevTools is convenient and free to use as part of Chrome. Reliability depends on the page state, loading behavior, and your verification of the image. Protocol automation can make capture repeatable, but it still needs explicit handling for navigation, dynamic content, timeouts, and output inspection. A screenshot records one visual state; it cannot establish that all asynchronous content or every logical page chunk was reached.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Its API returns a screenshot or PDF from one GET request. The service accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing status applied.

For a full-page screenshot, add full_page=true to the request. The API also supports custom CSS and JavaScript, selectors, wait conditions, request blocking, headers, cookies, user agents, caching, and other capture settings. See the ScreenshotNeo API documentation for parameter details.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -d full_page=true \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={
        "access_key": "YOUR_API_KEY",
        "url": "https://stripe.com",
        "full_page": "true",
    },
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
  full_page: 'true',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

Replace the example URL with the page you need. The MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. All features are available on every plan. Sign up free for 1,000 screenshots a month, no card required.

FAQ

Will a full-size screenshot include content that is below the fold?

It includes off-viewport page area. Whether that area contains fully loaded content depends on how the page loads and whether that content rendered before capture.

Does loading="eager" guarantee an image appears in the screenshot?

No. It removes lazy deferral for that image, but the request can still fail or remain unfinished, and eager loading alone does not raise its priority.

How do I capture every part of an infinite-scroll page?

Trigger each chunk by scrolling and wait for it to load, or use stable paginated URLs when the site provides them. Verify each captured state.

Can captureBeyondViewport load lazy content?

It controls screenshot extent in the DevTools Protocol. It is not a command to run a site’s scroll-driven loading behavior.