Cómo construir un benchmark de navegador que no pueda bloquearse
Los benchmarks fallan de maneras poco dignas. Se quedan colgados al 97 %. Dan una cifra que cambia un 30 % entre pruebas. Penalizan a un portátil por tener una pantalla mejor. Al reconstruir el nuestro para la versión 2.0, mantuvimos esos fallos a la vista y diseñamos una respuesta específica para cada uno. Estas son algunas notas del proceso.
Invertir la medición
La fórmula tradicional es una carga fija más los FPS medidos, y en un navegador resulta casi inútil: los equipos rápidos chocan con la frecuencia de actualización de la pantalla —el navegador no renderiza por encima del vsync, así que todos los buenos informan de «60» o «120»—, mientras que los lentos producen un pase de diapositivas que mide paciencia, no rendimiento.
Por eso fijamos el objetivo —un presupuesto de 16,67 ms por fotograma— y convertimos la carga en variable. Cada escena aumenta el número de partículas hasta que los fotogramas superan el presupuesto, aplica una búsqueda binaria al límite y exige después tres ventanas limpias consecutivas antes de aceptar un nivel. El resultado, la «carga estable máxima», tiene un significado físico imaginable: este equipo puede mover 840.000 partículas de nebulosa antes de empezar a perder fotogramas.
Un benchmark invertido también falla con elegancia por construcción. Un dispositivo modesto no produce una prueba rota; simplemente se estabiliza en un peldaño inferior de la misma escala.
Percentiles, porque los tirones engañan
Cada ventana se evalúa por su tiempo medio de fotograma y por su percentil 95. El criterio p95 existe porque las medias lavan los tirones: un equipo que entrega 95 fotogramas a tiempo y 5 a 40 ms se siente mal y aun así obtiene una media correcta. Los percentiles convierten ese «se siente mal» en un número. Una ventana anómala —una notificación, una pausa del recolector de basura— se repite en vez de contar como fallo, pero dos fallos consecutivos rechazan el nivel. Tolerante con los accidentes, inflexible con los patrones.
La máquina de estados paranoica
El requisito de «no puede bloquearse» produjo el código menos vistoso y más esencial del proyecto. Cada escena recorre una máquina de estados —preflight, baseline, warmup, ramp, bracket, confirm y anchor— y todos los estados tienen una salida estricta:
- una escena dispone de 30 segundos y una prueba, de 150; sin excepciones;
- al dejar la pestaña en segundo plano se invalida la ventana actual y la medición se pausa; más de 30 segundos oculta terminan la prueba con un motivo explícito;
- un cambio de tamaño o de relación de píxeles reconstruye la escena y repite el calentamiento, en vez de medir basura;
- la pérdida del contexto WebGL, una GPU sin entregar fotogramas durante varios segundos o una excepción de escena tienen cada una su propio motivo de salida; un watchdog sigue activo incluso cuando el bucle de renderizado no responde;
- Escape funciona en todos esos estados, porque un botón de cancelar que solo responde cuando todo va bien no es un botón de cancelar.
La prueba puede terminar antes de tiempo, degradada o cancelada. Lo único que no puede hacer es quedarse ahí para siempre.
Honestidad térmica
Una carga sostenida calienta el equipo; un equipo caliente reduce su velocidad; un benchmark que lo ignora mezcla en silencio el mejor minuto del dispositivo con el peor. Por eso cada escena mide dos veces una carga de referencia ligera: al principio y al final. Si la segunda lectura es más de un 15 % más lenta, la escena se marca como degradada. La marca llega a la hoja de resultados y a la puntuación —con una deducción limitada— y, si envías una muestra, también al conjunto de datos, para que las medianas públicas puedan excluir pruebas limitadas por temperatura en lugar de absorberlas.
Igualdad para pantallas de alta frecuencia
Una trampa sutil: si se juzga según su propio intervalo de actualización, un portátil de 120 Hz debe renderizar cada fotograma en 8,3 ms para «mantener la frecuencia», el doble de exigencia que un equipo de 60 Hz. Nuestro presupuesto es de 16,67 ms para todos. Las pantallas rápidas conservan su ventaja perceptible —muestran los fotogramas adicionales cuando la carga es ligera—, pero la línea de aprobado queda en el mismo sitio para cada panel. El monitor es una elección de visualización; el trabajo del benchmark es medir el equipo que hay detrás.
Lo que dejamos fuera a propósito
WebGPU todavía no: si llega, lo hará como un perfil independiente con su propio espacio de puntuación, nunca sustituido en silencio bajo el mismo número. Tampoco usamos web workers para el renderizado en esta versión; la superficie adicional de fallos —muerte del worker, transferencia de contexto, entrada entre hilos— chocaba con el requisito de no bloquearse, y la carga medida es idéntica. Y no mostramos percentiles en los resultados hasta que el conjunto de datos anónimo alcance umbrales reales: un percentil calculado con cuarenta pruebas es una intuición disfrazada de número.
La especificación completa, incluido el cálculo de la puntuación, está en la metodología. Si encuentras un dispositivo donde algo de lo anterior no se cumpla, es un error: admin at screentest.pro.