Symptoms & Diagnosis
Screen flickering in headless Chrome environments often occurs when the rendering engine struggles with hardware acceleration or resource allocation. You might notice rapid “blinking” in screen recordings or inconsistent visual artifacts in screenshots generated by Puppeteer or Playwright.
To diagnose the issue, check if the flickering persists in “headful” mode. If the glitch disappears when the browser is visible, the problem likely stems from how the headless environment handles the GPU or the lack of a physical display buffer.
Common indicators include black frames in video exports, partial element rendering, and logs showing “GPU process crashed” or “Context lost” errors.

Troubleshooting Guide
The primary solution involves passing specific configuration flags to the Chrome instance during the launch phase. This forces the browser to use more stable software-based rendering paths.
Disable Hardware Acceleration
Since headless environments often lack a real GPU, Chrome’s attempt to use hardware acceleration causes flickering. Use the following Node.js snippet to disable it:
const browser = await puppeteer.launch({
args: [
'--disable-gpu',
'--disable-software-rasterizer',
'--disable-dev-shm-usage'
]
});
Stabilize Rendering Flags
Certain Chrome features can trigger layout shifts or redraws that look like flickering. Use this table to apply the correct flags for your environment:
| Flag | Function |
|---|---|
| –hide-scrollbars | Prevents scrollbar recalculations from triggering redraws. |
| –no-sandbox | Reduces resource overhead in Docker environments. |
| –proxy-server=’direct://’ | Prevents proxy-related connection stutters. |
| –proxy-bypass-list=* | Speeds up local rendering by skipping proxy checks. |
Handle Shared Memory
If you are running Node.js in a Docker container, the default shared memory (/dev/shm) is often too small (64MB), causing the renderer to crash or flicker. Use the --disable-dev-shm-usage flag to force Chrome to use /tmp instead.
Prevention
To prevent flickering in future automated tasks, always ensure the viewport is set explicitly before performing any actions. Fluctuating viewport sizes trigger window-resize events that lead to visual glitches.
await page.setViewport({ width: 1920, height: 1080 });
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
Finally, implement a “wait for selector” strategy. Flickering often occurs when the script tries to capture a screenshot before the CSS transitions or heavy JavaScript frameworks have finished rendering the initial state.