Segmentar por dispositivo, red y tipo de página
Las dimensiones que hay que capturar junto a cada métrica, cómo obtenerlas sin identificar al usuario, y cuántos ejes se pueden cruzar antes de que los datos dejen de significar nada.
Una métrica agregada de todo el sitio y todos los dispositivos es casi siempre inútil: mezcla poblaciones cuya dificultad difiere en un factor grande, y se mueve cuando cambia la mezcla de tráfico en lugar de cuando cambia el rendimiento. Las dimensiones que capturas junto a cada muestra determinan qué preguntas vas a poder responder, y añadirlas después es imposible sobre los datos que ya recogiste.
- Enumerar las dimensiones esenciales y obtener cada una en el navegador.
- Distinguir dimensiones que informan del rendimiento de las que solo identifican al usuario.
- Aplicar el tipo de navegación para separar poblaciones que no son comparables.
- Limitar la cardinalidad para que las celdas conserven muestras suficientes.
Las dimensiones esenciales
Cinco dimensiones cubren la práctica totalidad de los diagnósticos.
Tipo de dispositivo. Es la más importante y no es negociable: los umbrales de las Core Web Vitals están calibrados por lo que es alcanzable en móvil, y en escritorio se aprueban con muchísima más facilidad. Una métrica sin esta dimensión no significa nada.
Tipo de página. No la URL exacta, que tiene cardinalidad ilimitada, sino la plantilla: portada, listado, ficha, buscador, carrito, artículo. Es lo que permite priorizar por impacto.
Tipo de navegación. Lo da la propia librería en metric.navigationType y separa poblaciones estructuralmente distintas.
Condiciones de red. Aproximadas, con las limitaciones que veremos.
Versión de la aplicación. El identificador del despliegue. Sin él no puedes atribuir una regresión a un cambio concreto.
El tipo de navegación
Este campo es el que más gente ignora y el que más sesgo elimina. Toma seis valores y cada uno describe una población distinta:
| Valor | Qué es | Por qué hay que separarlo |
|---|---|---|
navigate |
Navegación normal | La población de referencia |
reload |
Recarga | Caché caliente; casi siempre mucho más rápido |
back-forward |
Retroceso o avance sin caché de bfcache | Caché caliente parcial |
back-forward-cache |
Restauración desde la caché de retroceso y avance | Prácticamente instantáneo; contamina cualquier agregado |
prerender |
Página prerrenderizada | El LCP se mide desde la activación, no desde la navegación |
restore |
Pestaña descartada y restaurada por el usuario | Comportamiento anómalo |
El caso que más distorsiona es back-forward-cache. Una restauración desde esa caché tiene un LCP de decenas de milisegundos porque la página está entera en memoria. Si tu sitio tiene mucha navegación de ida y vuelta, esas visitas arrastran tu percentil 75 hacia abajo y te dan una imagen falsamente buena. Y lo peor: si un día haces un cambio que inhabilita esa caché, por ejemplo registrando un escuchador de unload, tu percentil empeorará bruscamente sin que ninguna carga se haya ralentizado. Separando por tipo de navegación, ese efecto se ve inmediatamente en lugar de convertirse en un misterio.
Filtra siempre a navigate para la métrica de referencia con la que tomas decisiones, y guarda el resto en dimensiones aparte. Si solo puedes permitirte una segmentación además del dispositivo, que sea esta.
Obtener las dimensiones en el navegador
Tipo de dispositivo. La forma robusta no es analizar la cadena de agente de usuario, sino usar las pistas de cliente cuando están disponibles y caer a una heurística cuando no:
function tipoDispositivo() {
// navigator.userAgentData existe en Chromium.
if (navigator.userAgentData) {
return navigator.userAgentData.mobile ? 'movil' : 'escritorio';
}
// Respaldo por consulta de medios, imperfecto pero estable.
return matchMedia('(pointer: coarse)').matches ? 'movil' : 'escritorio';
}
navigator.userAgentData está disponible en Chromium y no en los otros motores, de ahí el respaldo. La consulta (pointer: coarse) detecta un puntero impreciso, que en la práctica correlaciona bien con dispositivo táctil, aunque clasifica mal algunos portátiles con pantalla táctil.
Condiciones de red. La API de información de red expone una estimación:
function condicionesRed() {
const c = navigator.connection;
if (!c) return { tipo: 'desconocido' };
return {
tipo: c.effectiveType, // 'slow-2g' | '2g' | '3g' | '4g'
ahorroDatos: c.saveData === true,
};
}
Tres advertencias sobre esta API. Primera, solo está en Chromium; en el resto tendrás desconocido. Segunda, effectiveType no es el tipo de red física sino una clasificación por rendimiento observado: un wifi malo puede reportar 3g y una buena conexión móvil puede reportar 4g. Eso es lo que quieres, en realidad, porque lo que importa es el rendimiento efectivo. Tercera, el valor 4g agrupa todo lo que sea igual o mejor que 4G, incluida la fibra, así que no discrimina en el extremo bueno.
El campo saveData es interesante por otra razón: indica que el usuario ha pedido explícitamente ahorrar datos, lo cual es una señal de producto además de una dimensión de análisis.
Memoria del dispositivo. navigator.deviceMemory da una aproximación en gigabytes, redondeada a potencias de dos y limitada superiormente para no ser identificativa. Está en Chromium. Es un buen indicador de gama del dispositivo cuando está disponible.
Número de núcleos. navigator.hardwareConcurrency está ampliamente disponible y correlaciona razonablemente con la gama. Un dispositivo con dos núcleos y uno con doce no viven la misma web.
Versión de la aplicación. Inyéctala en el build, no la deduzcas:
// Sustituido en tiempo de construccion por tu empaquetador.
const VERSION = process.env.APP_VERSION;
Cuidado con las dimensiones que identifican
Hay una frontera que conviene no cruzar, tanto por regulación como por higiene.
Las dimensiones de esta lección describen condiciones técnicas, no personas: qué tipo de dispositivo, qué calidad de red, qué plantilla de página. Ninguna identifica a nadie por sí sola.
El problema aparece al cruzar muchas. La combinación de resolución exacta de pantalla, número de núcleos, memoria, zona horaria, idioma y lista de fuentes constituye una huella digital razonablemente única, y en ese momento tus datos de rendimiento se han convertido en datos personales sin que nadie lo haya decidido.
La regla práctica: redondea y agrupa en el cliente, antes de enviar. No envíes 1.170 por 2.532 píxeles, envía “móvil”. No envíes 7,7 gigabytes, envía el valor ya redondeado que la API te da. No envíes el agente de usuario completo si con navegador y versión mayor te basta. Y no añadas un identificador de sesión persistente a menos que tengas una razón concreta y un plan de retención.
Cuántos ejes se pueden cruzar
Este es el límite práctico que decide el diseño de tu panel. Cada eje multiplica el número de celdas, y cada celda necesita muestras suficientes para que su percentil signifique algo. Con la regla de que un percentil 75 estable necesita del orden de varios cientos de muestras:
100.000 visitas al mes
/ 2 tipos de dispositivo = 50.000 por celda
/ 6 tipos de pagina = 8.333 por celda
/ 4 tipos de red = 2.083 por celda
/ 4 tipos de navegacion = 520 por celda
/ 3 versiones desplegadas = 173 por celda <- ya es ruido
Con cien mil visitas mensuales, cruzar cinco ejes deja celdas de menos de doscientas muestras, cuyo percentil 75 fluctúa de forma que no se puede distinguir de un cambio real.
El diseño que funciona es guardar todas las dimensiones y cruzar pocas a la vez:
- Vista por defecto: dispositivo por tipo de página, filtrado a
navigate. Dos ejes. - Al investigar: añade un tercer eje concreto, y comprueba el recuento de muestras de cada celda antes de interpretarla.
- Nunca: un panel con cinco filtros desplegables que la gente combina a voluntad, porque acabarán mirando celdas de treinta muestras y sacando conclusiones.
Muestra siempre el recuento de muestras junto al percentil. Es la única defensa contra la sobreinterpretación, y cuesta una columna.
Todas las dimensiones anteriores describen las visitas que sí reportaron la métrica. La información que falta está en las que no lo hicieron, y es sistemática, no aleatoria. El INP no se reporta si nadie interactúa: una página cuyo INP mejora de repente puede simplemente haber dejado de ser usable, con los usuarios abandonando antes de tocar nada. El LCP no se reporta si la pestaña se cargó en segundo plano: si tu tráfico de una campaña abre pestañas en segundo plano, esa población desaparece. El CLS no se mide fuera de Chromium: si tu cuota de Safari sube, tu CLS medido describe a una fracción cada vez menor de tus usuarios sin que nada te avise. La solución es barata: registra el TTFB de todas las visitas, porque ocurre siempre y en todos los motores, y usa su volumen como denominador de todo lo demás. La proporción entre TTFB reportados y LCP reportados, o entre TTFB e INP, es una serie temporal que hay que vigilar igual que las métricas, porque cuando se mueve te está diciendo que la población que estás midiendo ha cambiado, y ese es el aviso que necesitas antes de interpretar cualquier otro número.