ScreenshotNeo

BlogHow-to

How to Screenshot a Lazy-Loading Webpage on a Slow Internet Connection

Capture a complete screenshot on slow internet: trigger lazy-loaded content, use Firefox or Playwright, and check the result for missing images.

By the ScreenshotNeo team4 October 20267 min read

Short answer: Scroll down the page in stages, pausing as newly visible images and content load, then take a full-page screenshot and inspect it for blanks or placeholders. On Firefox, use its full-page screenshot option. For repeatable captures, use Playwright with fullPage: true after scrolling the page to trigger lazy loading. Neither full-page capture nor a fixed delay guarantees that every site-specific element has loaded, especially on a slow connection.

A viewport screenshot records only what is visible in the browser window. A full-page screenshot extends beyond that viewport to capture the page’s scrollable content. Lazy-loaded images and other elements may not request or display their content until they approach the viewport, so capture the page after giving those elements a chance to load.

1. Use Firefox for a one-off screenshot

Firefox documents a built-in option to save a full-page screenshot. Interface labels can change between browser versions, so check the current Firefox support instructions if you do not see the option.

  1. Open the webpage and wait for its initial content to appear.
  2. Scroll down in stages. Pause when new sections enter the viewport and let their images or other content load.
  3. Continue to the bottom of the page, then use Firefox’s full-page screenshot option, documented as “Save full page.”
  4. Open the saved image and inspect the below-the-fold areas. If you see blank spaces or placeholders, return to the page, scroll through those sections again, wait for content, and capture again.

This route needs no code and is suitable for a manual, one-off capture. It does not make a slow network faster; it gives content more opportunity to load before the browser saves the page.

2. Capture with Playwright

Playwright’s screenshot API supports full-page capture. Its documentation describes this as capturing the full scrollable page. For lazy-loaded content, scroll through the document before capturing so scroll-triggered requests have a chance to run. The example below waits for each section to enter the viewport and allows the browser to render between steps. It deliberately does not assume one delay will work for every site or connection.

Runnable JavaScript example

Install Playwright and its Chromium browser in a Node.js project:

npm install playwright
npx playwright install chromium

Save the following as capture.js and run it with node capture.js https://example.com:

const { chromium } = require('playwright');

async function capture(url) {
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage({ viewport: { width: 1365, height: 900 } });

  try {
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });

    // Visit the page in viewport-sized steps to trigger scroll-based loading.
    await page.evaluate(async () => {
      const step = Math.max(400, window.innerHeight * 0.8);
      for (let y = 0; y < document.documentElement.scrollHeight; y += step) {
        window.scrollTo(0, y);
        await new Promise(resolve => setTimeout(resolve, 500));
      }
      window.scrollTo(0, 0);
    });

    // Capture after the scroll pass. Check the resulting file for missing content.
    await page.screenshot({ path: 'screenshot.png', fullPage: true });
  } finally {
    await browser.close();
  }
}

const url = process.argv[2];
if (!url) {
  console.error('Usage: node capture.js <url>');
  process.exit(1);
}
capture(url).catch(error => {
  console.error(error);
  process.exit(1);
});

The 500 ms pause is an example pacing value, not a recommended universal wait. Increase it if the page’s content is still loading as you scroll. For a page with a known load-more button, you may need to click that control as well; its behavior is specific to the site.

Playwright screenshot options

Option What it does When to use it
path Saves the screenshot to a file. Use a filename such as screenshot.png for a local capture.
fullPage: true Captures the full scrollable page rather than only the viewport. Use for a long-page screenshot after triggering lazy-loaded content.
type Selects an output format such as PNG or JPEG. Choose a format supported by the API and appropriate for your workflow.
clip Captures a specified rectangular area. Use for a region or section when an extremely tall full-page image is unwieldy.

See the Playwright screenshot guide and Page screenshot API reference for current options and details.

3. cURL, Python, and Node.js with ScreenshotNeo

When the task is to request a screenshot without managing a browser session, ScreenshotNeo provides a website screenshot API. A single GET request accepts a URL and returns a screenshot or PDF. Its capture options include full-page capture with lazy images loaded. See the ScreenshotNeo API documentation for parameters and formats.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com \
  -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', bytes));

These API examples use the service’s documented request pattern. Set the output format and other capture parameters as described in the API docs. ScreenshotNeo also supports selector-based capture, custom viewport and device presets, wait conditions, cookies, custom headers, custom CSS and JavaScript, request blocking, caching, signed image links, asynchronous jobs, and bulk capture. Use only the options the target page needs.

Or skip the browser setup

ScreenshotNeo can take a screenshot with one API call. It removes cookie banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing status. An MCP server gives AI agents access to screenshot, page-info, and PDF-capture tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Learn more at ScreenshotNeo.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://example.com \
  -o shot.webp

Sign up for 1,000 free screenshots a month, with no card.

4. Troubleshooting

Symptom Likely cause What to try
Images are blank or show placeholders The image request had not completed, or scrolling did not trigger the page’s lazy-loading behavior. Scroll through the affected section again, pause for the image to appear, then capture and inspect the result.
Only the visible screen appears in the file A viewport capture was used rather than a full-page option. Choose Firefox’s full-page save option or set Playwright’s fullPage: true.
Some sections are missing The site may load sections only on scroll, or require interaction such as a “load more” action. Scroll through the page in stages. Activate site controls when needed, then verify the saved screenshot.
Playwright navigation times out A slow page may not reach the selected navigation condition before the timeout. Use a suitable navigation condition such as domcontentloaded, allow a longer timeout when justified, and check the page itself before capture.
The full-page image is extremely tall The page has a large scroll height, which can make the resulting image difficult to inspect or handle. Capture sections separately with a clip or viewport workflow and verify each section. Stitching the sections is a separate step.
The screenshot differs from what a person sees Content may depend on session state, consent, geolocation, or interactive page behavior. Reproduce the required state with the browser or capture options, then inspect the saved output.

5. Slow-connection, reliability, and cost notes

  • There is no universal wait time. Network speed, image size, page scripts, and the site’s loading behavior vary. Wait until the content appears instead of relying on a fixed delay.
  • Full-page capture records a page state. It does not prove that all deferred requests completed. Inspect the image, especially below the fold.
  • Long pages need more care. A very tall screenshot can be harder to review and handle. Capturing sections can make missing content easier to spot.
  • Automation adds setup and maintenance. Playwright requires a Node.js project and browser installation. A site redesign or changed interaction can require updating the scroll or control logic.
  • Consider the work pattern when choosing an approach. Firefox is convenient for an occasional manual capture; Playwright supports repeatable scripts. ScreenshotNeo is an API option when you want to request captures without managing browser setup. Its listed plans are Free: 1,000 per month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan.

FAQ

Does fullPage: true make Playwright load every lazy image?

No. It requests a full-page capture, but scroll-triggered behavior may not have run for every element. Scroll the page before capture and inspect the output.

Can I use a full-page screenshot when the page is still loading?

You can capture the current page state, but resources that have not arrived may be blank or incomplete. Wait for the relevant content and check the resulting file.

Should I capture a very long page as one image?

It depends on how you will review or use it. If a single tall image is unwieldy, capture and verify sections separately.

Can I automate a “load more” button?

Yes, if you identify the site-specific control and add an interaction to your script. The control and loading behavior vary by site, so verify that new content appeared before taking the final capture.

Sources