ScreenshotNeo

BlogHow-to

How to Compress Playwright Screenshot Files Without Losing Clarity

Make Playwright screenshots smaller by choosing the right scale, capture area, and format. Keep text and fine details clear with a workflow for lossless images, sharing, and visual tests.

By the ScreenshotNeo team4 October 20268 min read

To make Playwright screenshots smaller without making them blurry, first reduce unnecessary pixels: set scale: 'css' when device-pixel detail is not needed, and capture only the viewport, element, or clipped region that matters. For pixel-sensitive evidence and visual regression tests, use PNG or WebP at quality 100; for screenshots meant for sharing, test lower WebP quality on representative pages and inspect the result. There is no universal quality setting or guaranteed file-size reduction.

Playwright supports PNG, JPEG, and WebP. PNG does not use the quality option. WebP at quality 100 is lossless, while lower values are lossy. JPEG is lossy and defaults to quality 80 in the documented Page API, so check text, thin borders, and icons before adopting it. [Playwright Page API]

Choose the smallest capture that still answers the question

Compression is only one way to reduce bytes. The screenshot’s dimensions and captured area determine how many pixels must be encoded in the first place. Keep the relevant details at their needed resolution, and avoid storing parts of the page that do not matter.

Capture choice Use it when Trade-off
Viewport The visible screen is the evidence. Content below the viewport is not included.
Element A particular component is under review. Only that element is captured.
Clip A specific rectangular region matters. Anything outside the rectangle is excluded.
Full page You need content below the fold. The image can be much taller than a viewport capture.

Use scale: 'css' for one image pixel per CSS pixel. scale: 'device' preserves device-pixel resolution; on high-DPI displays this can make screenshots twice as large or larger. CSS scale is often suitable for ordinary page evidence. Preserve device scale when high-density rendering detail is part of what you need to inspect. [Playwright Page API]

Capture with Playwright and choose an output format

The following runnable Node.js example captures a viewport as WebP. It uses CSS-pixel scale and quality 100 to preserve lossless WebP output. Change the format and options to match your use case.

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

(async () => {
  const browser = await chromium.launch();
  try {
    const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
    await page.goto('https://example.com', { waitUntil: 'load' });
    await page.screenshot({
      path: 'page.webp',
      type: 'webp',
      quality: 100,
      scale: 'css',
      fullPage: false,
    });
  } finally {
    await browser.close();
  }
})();

Install Playwright in a project with npm install playwright. Depending on your setup, install the browser binaries as directed by the official installation guide. The Page API documents screenshot options and supported formats.

Format and quality options

  • PNG: Lossless and useful when exact pixels matter. The screenshot API does not apply a quality setting to PNG.
  • WebP, quality 100: Documented as lossless. It is a good candidate when you need a lossless screenshot in a modern image format.
  • WebP, quality below 100: Lossy. Lower values can reduce bytes but may soften text, icons, gradients, or fine borders. Compare actual output files rather than assuming a particular setting will be acceptable.
  • JPEG: Lossy, with documented default quality 80. Treat it as a sharing format to evaluate visually, not a conservative choice for pixel comparisons.

The API’s documented quality range is 0–100 and applies to JPEG and WebP; PNG ignores it. WebP at 100 is lossless, while a lower WebP quality uses lossy compression. Check the documentation for the Playwright version installed in your project if defaults or supported options matter. [Page API]

Capture only an element or clipped area

For a component screenshot, locate the element and capture it directly:

const card = page.locator('.pricing-card').first();
await card.screenshot({
  path: 'pricing-card.png',
  type: 'png',
  scale: 'css',
});

For a fixed region, use a clip rectangle with the page screenshot:

await page.screenshot({
  path: 'chart.webp',
  type: 'webp',
  quality: 100,
  scale: 'css',
  clip: { x: 120, y: 180, width: 720, height: 420 },
});

Coordinates and dimensions are in CSS pixels. Make sure the clip covers the content you need; a smaller file is not useful if it cuts off labels or context.

Full-page capture

When below-the-fold content is required, set fullPage: true. Combine it with an appropriate format and scale:

await page.screenshot({
  path: 'whole-page.webp',
  type: 'webp',
  quality: 100,
  scale: 'css',
  fullPage: true,
});

Full-page capture includes more image area, so it can create a substantially larger file than a viewport shot. Do not use it by default if the test or report only needs the visible screen.

Use a different workflow for visual regression

For screenshot assertions, keep baselines in a lossless format. Playwright’s assertion documentation describes PNG and WebP snapshots as lossless. JPEG compression can alter pixels around text and edges, making exact visual comparisons less suitable. If you change scale, dimensions, browser settings, or image format, review the resulting baseline changes and validate them against the test suite. [Playwright visual comparisons]

For ordinary screenshots shared with people, a lossy WebP setting may be acceptable. Choose it by checking representative pages at the size and display conditions your readers use. Inspect small text, thin lines, icons, gradients, and areas with subtle color changes. The official API documentation defines the format behavior, but does not establish a universally suitable lossy quality value or file-size saving.

Post-process a screenshot buffer when built-in options are not enough

Playwright can return screenshot data as a buffer instead of writing directly to a file. That lets you pass the bytes to your own processing stage or a pixel-diff tool. The official screenshot guide describes this workflow but does not endorse a particular third-party optimizer, so evaluate any processing library against your own requirements. [Playwright screenshots guide]

const imageBuffer = await page.screenshot({
  type: 'png',
  scale: 'css',
});

// Pass imageBuffer to your chosen processing or comparison step.
// Keep the original buffer if you need an exact reference.

Check that post-processing preserves transparency and color as required, and that text and fine edges still look acceptable. For regression baselines, compare processed output to the expected image and avoid lossy processing unless your comparison method accounts for it.

A practical decision checklist

  1. Decide whether pixels must match exactly. Use PNG or WebP quality 100 for pixel-sensitive evidence and test baselines.
  2. Pick the needed resolution. Use CSS scale when device-pixel detail is not needed; keep device scale when it is.
  3. Pick the smallest meaningful area. Prefer an element, clip, or viewport capture if full-page content is unnecessary.
  4. For sharing, evaluate lossy WebP. Start with representative pages and inspect small details at the intended display size.
  5. Measure your own output. Record file bytes and check visual quality; savings vary with page content and configuration.
  6. Keep comparison inputs consistent. Use the same viewport, scale, browser conditions, and capture area when comparing images.

Or skip the browser setup

If you need a screenshot without managing a browser instance, ScreenshotNeo provides a website screenshot API: one GET request with a URL returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo site and API documentation for the available 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,
)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo removes cookie and consent 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. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, no card required.

Troubleshooting

Symptom Likely cause What to try
The file is still large The screenshot captures too many pixels, uses device scale, or includes the full page. Use CSS scale if suitable and capture only the needed viewport, element, or clip. Compare dimensions and byte size.
Text looks soft or has halos A lossy format or quality setting changed fine edges. Use PNG or WebP quality 100 for exact detail. If lossy output is needed, test a higher quality and inspect representative text.
Quality has no effect on a PNG The PNG screenshot option does not use quality. Choose WebP or JPEG if you want a lossy quality setting, or keep PNG for lossless output.
A screenshot differs from a test baseline Format, scale, viewport, capture area, or rendering conditions may differ. Keep these inputs consistent. For pixel-sensitive assertions, use PNG or WebP snapshots and review configuration changes.
The clip omits content The rectangle is too small or positioned incorrectly. Adjust the CSS-pixel coordinates and dimensions, then inspect the captured area.
A full-page screenshot is unexpectedly tall fullPage: true includes content beyond the viewport. Use viewport or element capture if below-the-fold content is not needed.
The capture call fails before writing an image The page navigation, browser launch, or screenshot operation failed. Surface the thrown error, verify the browser installation and target page access, and ensure the browser is closed in a finally block.

Performance, reliability, and storage costs

Reducing image dimensions with CSS scale or a smaller capture area reduces the number of pixels that must be encoded and stored. The amount of byte savings depends on the page, format, and options; the official documentation does not provide a general benchmark or percentage. Lossy encoding can further reduce file size, with visible artifacts as the trade-off.

For reliable comparisons, keep viewport, scale, capture region, and format stable between runs. Preserve a lossless original if you post-process screenshots that may later serve as evidence. For storage planning, measure representative output files and multiply by the number of captures you retain; include any duplicate originals and test artifacts in that estimate.

FAQ

Does lowering WebP quality always make the image unclear?

No single threshold applies to every page. Lower quality is lossy, so inspect the details your use case depends on before adopting it.

Should I use JPEG for visual tests?

For pixel-sensitive comparisons, PNG or WebP is the safer choice because Playwright’s assertion documentation describes those formats as lossless.

Is CSS scale the same as resizing an image afterward?

No. CSS scale controls screenshot output pixels relative to CSS pixels at capture time. Post-processing changes an already captured image and may introduce its own effects.

Is there a guaranteed file-size reduction from these settings?

No. The result depends on page dimensions and content, format, and quality. Measure files from representative pages.

Sources