Cómo acelerar WebGL sin GPU: el truco de un flag de Chrome

Fuentes: WebGL without a GPU

Microlink opera una flota de navegadores sobre nodos Linux sin tarjeta gráfica ni /dev/dri, una decisión que abarata costes y reduce drivers, pero que obliga a renderizar WebGL por software. En ese contexto, el cuello de botella eran las capturas de páginas 3D, ya que SwiftShader, el motor software integrado en Chrome, tardaba unos 24 segundos por escena y, además, provocaba timeouts bajo carga.

La clave estaba en cambiar el backend que Chrome delega para WebGL: ANGLE. Sustituir SwiftShader por Mesa llvmpipe mediante el flag --use-angle=gl rebajó el tiempo a unos 6 segundos en pruebas aisladas y a 7-14 segundos bajo carga real, una mejora cercana a 4×. ¿Por qué? llvmpipe compila en tiempo de ejecución con LLVM a código nativo x86-64 y aprovecha todos los núcleos con renderizado tileado y multihilo, frente al enfoque conservador de SwiftShader.

El cambio en sí es de una sola línea, pero el resto fue trabajoso. El flag exige un display X (aunque sea virtual con Xvfb) y la variable LIBGL_ALWAYS_SOFTWARE=1 para forzar llvmpipe. Como Ubuntu Jammy trae una Mesa demasiado antigua, la imagen base la compila desde fuente con Meson, incluyendo solo llvmpipe y LLVM compartido, y reduce el peso de 4,5 GB a 2,65 GB con un Dockerfile multi-etapa.

Para evitar regresiones, browserless.report() consulta el contexto GL real del proceso (no el paquete del sistema) y actúa como puerta de CI: exige gpu.type = software y gpu.device = llvmpipe, fallando el build si el render vuelve al fallback 2D plano, que parece éxito pero produce páginas incorrectas. La compañía concluye que buena parte del esfuerzo fue medir bien: las máquinas de desarrollo engañan, las ejecuciones únicas también, y solo un benchmark determinista de shaders permitió comparar nodos con un número estable.