ScreenshotNeo

BlogComparisons

Chrome Headless vs Playwright for Scheduled Website Screenshots

Compare Chrome Headless and Playwright for scheduled website screenshots, with runnable examples, scheduling guidance, troubleshooting, and a practical choice guide.

By the ScreenshotNeo team4 October 202610 min read

Direct answer: Use Chrome Headless when each scheduled run captures a URL at a fixed viewport and needs little page interaction. Use Playwright when the job must navigate, wait for specific page states, capture a selected element or full page, mask changing content, or control browser behavior in code. Neither is a universal speed or reliability winner; the official documentation reviewed publishes no comparative benchmark.

Both tools render pages in a browser. Neither schedules itself: cron, a CI scheduler, a task queue, or a cloud scheduler must launch the recurring job. This guide shows how to set up both approaches, make output repeatable, handle failures, and decide when a browser-managed screenshot service is a better fit.

1. Choose the capture method

Need Good starting point Why
Capture a URL at a fixed viewport and save an image Chrome Headless CLI A direct command supports screenshot output, viewport sizing, and a capture timeout.
Wait for a selector, interact with the page, or capture one element Playwright Its Page API provides navigation and programmable screenshot controls.
Capture an entire page Playwright Full-page capture is an explicit screenshot option.
Reduce visual-test noise from animation or changing regions Playwright Screenshot controls include animation handling and masks; visual comparison guidance also recommends controlling the environment.
Keep a small, fixed command launched on a schedule Chrome Headless CLI The scheduler can invoke a script or command at the desired interval.
Run browser automation logic before capture Playwright Navigation and page operations can live in the same program as the screenshot call.

The distinctions above reflect documented interfaces, not benchmark results. See the Chrome Headless command-line reference and Playwright’s Page API.

2. Schedule a basic capture with Chrome Headless

Chrome’s CLI is suitable when the job can be expressed as a URL, a viewport, and an output file. Install Chrome in the machine or container that runs the job, then use its executable path in the scheduled script.

google-chrome --headless --screenshot=artifacts/homepage.png --window-size=1440,1000 --timeout=15000 https://example.com

The command writes a screenshot file. Replace google-chrome with the executable name or full path used by your OS image. Chrome documents --screenshot, --window-size, and --timeout for capture operations. The timeout is a limit for the capture operation; it is not a guarantee that every site’s relevant content has finished loading.

Put the command in a repeatable script

#!/usr/bin/env bash
set -euo pipefail

url="${1:?Usage: capture.sh URL}"
output_dir="${OUTPUT_DIR:-artifacts}"
mkdir -p "$output_dir"
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
output="$output_dir/shot-$timestamp.png"

google-chrome \
  --headless \
  --screenshot="$output" \
  --window-size=1440,1000 \
  --timeout=15000 \
  "$url"

test -s "$output"
printf 'Saved %s\n' "$output"

Save this as capture.sh, make it executable with chmod +x capture.sh, and invoke it from your scheduler with the target URL. The non-empty file check makes a missing or zero-byte artifact fail the job. Add your own reporting and retention policy around this script.

3. Schedule a capture with Playwright

Playwright is the better fit when the screenshot depends on page state or capture controls. The following Node.js example navigates to a page, waits for a meaningful selector, and saves a full-page PNG.

// capture.mjs
import { chromium } from 'playwright';

const url = process.argv[2];
if (!url) throw new Error('Usage: node capture.mjs URL');

const browser = await chromium.launch({ headless: true });
try {
  const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30_000 });
  await page.locator('main').waitFor({ state: 'visible', timeout: 15_000 });
  await page.screenshot({ path: 'artifacts/page.png', fullPage: true, animations: 'disabled' });
} finally {
  await browser.close();
}

Install the package and browser in the runtime used by your scheduler:

npm install playwright
npx playwright install chromium
mkdir -p artifacts
node capture.mjs https://example.com

Change main to a selector that represents content your target page actually has. If you only need the current viewport, remove fullPage: true. The example disables finite animations during capture; Playwright documents screenshot options for animations and masks, along with full-page capture, in its screenshot API.

Capture a specific element or mask dynamic content

const report = page.locator('[data-report]');
await report.screenshot({ path: 'artifacts/report.png', animations: 'disabled' });

await page.screenshot({
  path: 'artifacts/dashboard.png',
  fullPage: true,
  animations: 'disabled',
  mask: [page.locator('.live-clock'), page.locator('.rotating-promo')]
});

Element screenshots are useful when a page contains unrelated navigation or footers. Masks can cover known dynamic regions in visual captures; choose selectors carefully because a missing or overly broad selector can hide a real change. See Playwright’s Page API options for the current option details.

4. Choose and pin the browser runtime

Playwright’s browser choice affects what is installed and can affect rendering. Its browser documentation describes a regular Chromium build, a separate headless shell used by default for headless Chromium, and the chromium channel for opting into new headless mode. It also supports branded Chrome and Edge channels.

  • Default Playwright Chromium: Use the browser build installed for your Playwright version; install it in the runtime image as part of deployment.
  • Headless shell: Playwright uses this separately for headless Chromium by default. The install option --only-shell is documented for CI that only uses the headless shell.
  • New headless mode: Set the Chromium channel to chromium when you specifically want that mode. Playwright documents --no-shell for installing without the separate headless shell.
  • Branded Chrome or Edge: Playwright supports browser channels, but managed enterprise browser policies may affect automation control.

For a recurring visual baseline, pin the Playwright version, browser build, OS image, fonts, viewport, and relevant settings. Playwright notes that screenshots can vary with operating system, browser version, settings, hardware, power source, and headless mode. Its guidance recommends generating and checking visual baselines in the same environment. Read Playwright browser management and visual comparisons.

5. Connect either capture to a scheduler

The scheduler is deployment-specific; neither Chrome’s CLI nor Playwright requires one. Common choices are cron on a host, a scheduled CI workflow, a task queue, or a cloud scheduler that starts a container. Configure these operational details explicitly:

  1. Interval and timezone: Decide the cadence and whether it follows UTC or a local timezone. Avoid ambiguous daylight-saving transitions for time-based jobs.
  2. Inputs: Keep target URLs, viewport dimensions, and selectors in configuration. Validate URLs before launching a browser.
  3. Wait condition and timeout: Prefer a meaningful selector or page state when a page has delayed content. Set navigation and capture limits that fit the job’s runtime budget.
  4. Artifact naming: Include a stable page identifier and UTC timestamp, or overwrite a known “latest” file in addition to retaining dated captures.
  5. Failure policy: Record the URL, run time, browser version, and error. Retry transient failures with a bounded policy; repeated retries can amplify load on a site that is down.
  6. Retention: Set storage lifecycle rules based on comparison and audit needs. Screenshots can contain private or personal information.
  7. Secrets: Keep credentials and tokens in the scheduler or runtime’s secret store. Do not put them in a public command log or artifact name.

These are implementation choices, not requirements imposed by the reviewed browser documentation. For CI, Playwright’s guidance says browsers launch headlessly by default, discusses launch debugging, and cautions that restoring a browser binary cache can take about as long as downloading it; Linux dependencies still need installation. Treat cache value as specific to your CI environment. See Playwright CI guidance.

6. Make recurring screenshots comparable

Headless capture does not make images identical across runs. Pages change, and rendering can vary with the environment. To make comparisons useful:

  • Use the same browser version and OS image for every run in a comparison series.
  • Keep viewport dimensions, device scale behavior, fonts, timezone, locale, and color scheme consistent where they matter.
  • Wait for a page-specific ready condition instead of relying on a short arbitrary delay.
  • Disable or mask known animation and frequently changing regions when those are not the subject of the check.
  • Keep separate baselines when intentionally comparing different browsers, operating systems, or viewport sizes.
  • Use a stable output convention and preserve the metadata needed to interpret a screenshot later.

Playwright’s visual comparison documentation explains environment-dependent rendering variation and recommends using the same environment for baseline generation and checking. A matching environment reduces avoidable differences; it cannot prevent genuine page changes or every source of nondeterminism.

7. Troubleshoot common failures

Symptom Likely cause What to do
Chrome command is not found The executable name or path differs in the host/container. Install Chrome in the execution image and use its actual binary path. Confirm the same user running the scheduler can execute it.
Playwright reports that a browser executable is missing The package is installed but its matching browser build is not. Install the required browser with Playwright’s browser installation command in the same image or runtime.
Browser launch fails in CI Browser dependencies or permissions are missing, or the selected runtime differs from local development. Use Playwright’s CI guidance to install browser dependencies and investigate launch logs. Reproduce with the same OS image and browser build.
Screenshot shows a loading state or missing content The capture ran before the relevant content was ready, or the page’s network never settled. Wait for a page-specific visible selector or state. Increase a timeout only after checking that the page can reach that state.
Capture times out The page is slow, a request hangs, or the configured limit is too short for the target. Inspect navigation and resource behavior, use a meaningful readiness condition, and set a bounded timeout appropriate to the job.
Screenshot dimensions are unexpected The viewport was not configured, or full-page capture was enabled. Set an explicit viewport/window size. In Playwright, check whether fullPage is enabled; in Chrome, review --window-size.
Images differ between otherwise similar runs Browser, OS, fonts, hardware, headless mode, animation, or live content changed. Pin the rendering environment, wait consistently, and disable or mask intentionally dynamic regions. Maintain separate baselines for different environments.
Scheduled run succeeds but artifact is absent The output directory may not exist, the scheduler may use another working directory, or the artifact was not uploaded. Use an explicit output path, create the directory, check for a non-empty file, and configure artifact upload or storage.
Artifacts grow without bound Every run creates a retained file and no lifecycle policy removes old captures. Define a retention period or cap and apply storage lifecycle cleanup.

8. Performance, reliability, and cost

There is no source-backed universal timing comparison between Chrome Headless and Playwright here. A direct Chrome command has a compact operational shape for a simple capture, while Playwright offers more page controls in exchange for application code and browser setup. Actual duration depends on page behavior, browser startup, machine resources, and the readiness condition.

For reliability, record failures rather than silently treating a missing image as success. Apply bounded retries for transient errors, alert on persistent failures, and keep the browser/runtime pinned when consistency matters. A capture can complete while still depicting an error page or incomplete content, so check expected page content when correctness matters.

Cost comes from the runtime, scheduler, compute, network, and artifact storage you choose. Consider browser installation and maintenance, job frequency, full-page image size, retained history, and concurrent jobs. The reviewed official browser documentation does not specify a scheduler, retry policy, storage price, or retention period; estimate those using your own infrastructure and workload.

9. Or skip the browser setup

If you need the screenshot result without installing and scheduling a browser yourself, ScreenshotNeo is a website screenshot API and MCP server. One GET request captures a URL as PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Cookie banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether the request was billed. The MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. Free includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan and get 1,000 screenshots a month with no card.

10. Frequently asked questions

Does Chrome Headless or Playwright provide the schedule?

No. A scheduler or job runner must start the capture command or program.

Can Playwright take a screenshot without opening a visible browser window?

Yes. Playwright launches browsers headlessly by default in its CI guidance.

Will the same scheduled capture always produce identical pixels?

No. Browser and host environment differences, dynamic page content, and rendering conditions can change pixels between runs.

Which should I use for a simple recurring URL capture?

Start with Chrome Headless CLI if a fixed viewport and straightforward output are enough. Choose Playwright when the job needs page-level logic or more capture controls.