Blog

Xvfb: guia prático e como obter renderização real na GPU

xvfb-run numa linha para Playwright, Selenium e Puppeteer. Porque é que o Xvfb renderiza na CPU (llvmpipe) e como pôr o Chrome a usar a GPU, com medições.

Xvfb: guia prático e como obter renderização real na GPU

O Xvfb (X virtual framebuffer) é um servidor X que desenha na memória em vez de num ecrã. É a forma clássica de lançar um navegador, uma aplicação gráfica ou uma suite de testes E2E num servidor Linux sem ecrã. Este guia mostra o essencial e, depois, o limite que a maioria dos tutoriais esquece: o Xvfb não passa pela GPU.

Arrancar numa linha

sudo apt install xvfb          # Debian / Ubuntu
xvfb-run -a -s "-screen 0 1920x1080x24" npx playwright test
  • -a escolhe automaticamente um número de display livre (útil em CI paralela);
  • -screen 0 1920x1080x24 fixa a resolução e a profundidade: as capturas de ecrã são idênticas de uma execução para a outra.

Para manter um display aberto em segundo plano:

Xvfb :99 -screen 0 1920x1080x24 &
export DISPLAY=:99

A armadilha: o Xvfb renderiza na CPU

O Xvfb não tem acesso à GPU. Qualquer aplicação OpenGL lançada nele é renderizada pela CPU, com o driver de software llvmpipe do Mesa:

$ xvfb-run -a glxinfo -B | grep renderer
OpenGL renderer string: llvmpipe (LLVM 19.1.7, 256 bits)

Com o Chrome e o Chromium é ainda mais claro. Sob Xvfb sem configuração, o WebGL fica simplesmente desativado; em modo --headless sem configuração, o Chrome usa o SwiftShader, uma GPU emulada na CPU. Num teste WebGL 1080p, isso dá cerca de 13 imagens/s.

Pôr o Chrome a usar a GPU, com ou sem Xvfb

O Chrome consegue renderizar diretamente na GPU via ANGLE, sem passar pelo servidor X. Basta pedir-lho:

chromium --headless=new --use-angle=vulkan --ignore-gpu-blocklist ...

Medido a 29/10/2026 num servidor Linux GPU (Intel UHD 770, 4 vCPU, Chromium 156, mesmo shader WebGL 1080p):

ConfiguraçãoMotor de renderização WebGLImagens/s
--headless=new sozinhoSwiftShader (CPU)13
Xvfb sozinhoWebGL desativado—
--headless=new --use-angle=vulkanUHD 770 (Vulkan)~260
--headless=new --use-angle=gl-eglUHD 770 (OpenGL ES 3.2)~230
Xvfb + --use-angle=vulkanUHD 770 (Vulkan)GPU, como acima

Cerca de 20 vezes mais rápido, e a CPU fica livre para os seus testes. As mesmas opções funcionam sob Xvfb: útil se mantiver o Xvfb para uma extensão ou uma aplicação que exija um display X real.

O detalhe (Playwright, Puppeteer, Selenium, Docker, verificação) está no nosso guia Lançar o Chrome com GPU num servidor Linux.

Ainda preciso do Xvfb?

CasoXvfb útil?
Playwright / Puppeteer / Selenium recentesNão: --headless=new basta
Extensões do Chrome, testes em modo «headed»Sim
Aplicações X11 (Electron, Java Swing, ferramentas antigas)Sim
OpenGL acelerado para uma aplicação que não é um navegadorNão: use EGL sem display, ou VirtualGL

Perguntas frequentes

Porque é que as minhas capturas WebGL saem pretas ou muito lentas sob Xvfb? Porque o Chrome desativa o WebGL (ou passa para o SwiftShader) quando não encontra GPU. Acrescente --use-angle=vulkan --ignore-gpu-blocklist.

É possível ter OpenGL por hardware sob Xvfb? Não diretamente: o Xvfb não sabe usar a GPU. As aplicações que sabem renderizar via EGL (eglinfo -B -p surfaceless mostra a placa) ou o VirtualGL contornam o problema.

É reproduzível em CI? Sim: a resolução e a profundidade são fixadas pelo comando, e a GPU dá a mesma renderização em cada execução.

Experimentar num servidor Linux GPU

Os nossos servidores têm uma GPU Intel UHD 770 acessível na VM, com Mesa, Vulkan e VAAPI já instalados: instale o Chromium (apt install chromium) e os comandos acima funcionam de imediato. A partir de 14,99 € s/ IVA/mês, acesso root, IPv6 dedicado, opção cluster k3s.