Saltar al contenido principal




Un tutorial sobre el uso de WebPageTest para identificar y solucionar problemas de inestabilidad de diseño.

En una publicación anterior escribí sobre medir el cambio de diseño acumulativo (CLS) en WebPageTest. CLS es una agregación de todos los cambios de diseño, por lo que en esta publicación pensé que sería interesante profundizar e inspeccionar cada cambio de diseño individual en una página para tratar de comprender qué podría estar causando la inestabilidad y realmente intentar solucionar el problema ( s).

Medición de cambios de diseño

Usando la API de Layout Inestabilidad, podemos obtener una lista de todos los eventos de cambio de diseño en una página:

new Promise(resolve => {
new PerformanceObserver(list => {
resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
}).observe({type: "layout-shift", buffered: true});
}).then(console.log);

Esto produce una serie de cambios de diseño que no están precedidos por eventos de entrada:

[
{
"name": "",
"entryType": "layout-shift",
"startTime": 210.78500000294298,
"duration": 0,
"value": 0.0001045969445437389,
"hadRecentInput": false,
"lastInputTime": 0
}
]

En este ejemplo, hubo un solo cambio muy pequeño de 0.01% a 210ms.

Conocer el tiempo y la gravedad del cambio es útil para ayudar a reducir qué pudo haber causado el cambio. Volvamos a WebPageTest para que un entorno de laboratorio realice más pruebas.

Medición de cambios de diseño en WebPageTest

De manera similar a medir CLS en WebPageTest, medir cambios de diseño individuales requerirá una métrica personalizada. Afortunadamente, el proceso es más fácil ahora que Chrome 77 es estable. La API de Layout Inestabilidad está habilitada de forma predeterminada, por lo que debería poder ejecutar ese fragmento JS en cualquier sitio web dentro de Chrome 77 y obtener resultados de inmediato. En WebPageTest, puede usar el navegador Chrome predeterminado y no tener que preocuparse por los indicadores de la línea de comandos o usar Canary.

Así que modifiquemos ese script para producir una métrica personalizada para WebPageTest:

[LayoutShifts]
return new Promise(resolve => {
new PerformanceObserver(list => {
resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
}).observe({type: "layout-shift", buffered: true});
});

La promesa en este script se resuelve en una representación JSON de la matriz en lugar de la matriz en sí. Esto se debe a que las métricas personalizadas solo pueden producir tipos de datos primitivos como cadenas o números.

El sitio web que usaré para la prueba es ismyhostfastyet.com, un sitio que creé para comparar el rendimiento de carga de los servidores web en el mundo real.

Identificar las causas de la inestabilidad del diseño

En el resultados podemos ver que la métrica personalizada LayoutShifts tiene este valor:

[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3087.2349999990547,
"duration": 0,
"value": 0.3422101449275362,
"hadRecentInput": false,
"lastInputTime": 0
}
]

En resumen, hay un cambio de diseño único del 34,2% a 3087ms. Para ayudar a identificar al culpable, usemos WebPageTest’s vista de tira de película.

layout-shift1-2742295
Dos celdas en la tira de película, que muestran capturas de pantalla antes y después del cambio de diseño.

Desplazarse hasta la marca de ~ 3 segundos en la tira de película nos muestra exactamente cuál es la causa del cambio de diseño del 34%: la mesa colorida. El sitio web recupera de forma asincrónica un archivo JSON y luego lo convierte en una tabla. La mesa está inicialmente vacía, por lo que esperar a llenarla cuando se cargan los resultados está provocando el cambio.

layout-shift2-9850265
Encabezado de fuente web que aparece de la nada.

Pero eso no es todo. Cuando la página se completa visualmente en ~ 4.3 segundos, podemos ver que el <h1> de la página «¿Mi anfitrión ya es rápido?» aparece de la nada. Esto sucede porque el sitio usa una fuente web y no ha tomado ningún paso para optimizar la representación. En realidad, el diseño no parece cambiar cuando esto sucede, pero sigue siendo una mala experiencia para el usuario tener que esperar tanto tiempo para leer el título.

Arreglar la inestabilidad del diseño

Ahora que sabemos que la tabla generada de forma asincrónica está provocando que un tercio de la ventana gráfica se desplace, es hora de solucionarlo. No conocemos el contenido de la tabla hasta que se cargan los resultados JSON, pero aún podemos completar la tabla con algún tipo de datos de marcador de posición para que el diseño en sí sea relativamente estable cuando se renderiza el DOM.

Aquí está el código para generar datos de marcador de posición:

function getRandomFiller(maxLength) {
var filler = '█';
var len = Math.ceil(Math.random() * maxLength);
return new Array(len).fill(filler).join('');
}

function getRandomDistribution() {
var fast = Math.random();
var avg = (1 - fast) * Math.random();
var slow = 1 - (fast + avg);
return [fast, avg, slow];
}


window.data = [];
for (var i = 0; i < 36; i++) {
var [fast, avg, slow] = getRandomDistribution();
window.data.push({
platform: getRandomFiller(10),
client: getRandomFiller(5),
n: getRandomFiller(1),
fast,
avg,
slow
});
}
updateResultsTable(sortResults(window.data, 'fast'));

Los datos del marcador de posición se generan aleatoriamente antes de ser ordenados. Incluye el carácter «█» repetido un número aleatorio de veces para crear marcadores de posición visuales para el texto y una distribución generada aleatoriamente de los tres valores principales. También agregué algunos estilos para desaturar todos los colores de la tabla para dejar en claro que los datos aún no están completamente cargados.

La apariencia de los marcadores de posición que usa no importa para la estabilidad del diseño. El propósito de los marcadores de posición es asegurar a los usuarios que el contenido es viene y la página no está rota.

Así es como se ven los marcadores de posición mientras se cargan los datos JSON:

layout-placeholder-7909400
La tabla de datos se representa con datos de marcador de posición.

Abordar el problema de las fuentes web es mucho más sencillo. Debido a que el sitio usa Google Fonts, solo necesitamos pasar el display=swap propiedad en la solicitud CSS. Eso es todo. La API de fuentes agregará font-display: swap estilo en la declaración de fuente, lo que permite al navegador representar el texto en una fuente alternativa inmediatamente. Aquí está el marcado correspondiente con la corrección incluida:

<link href="https://fonts.googleapis.com/css?family=Chivo:900&amp;display=swap" rel="stylesheet">

Verificando las optimizaciones

Después de volver a ejecutar la página a través de WebPageTest, podemos generar un antes y un después comparación para visualizar la diferencia y medir el nuevo grado de inestabilidad del diseño:

layout-comparison-2278210
Tira de película de WebPageTest que muestra ambos sitios que se cargan uno al lado del otro con y sin optimizaciones de diseño.

[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3070.9349999997357,
"duration": 0,
"value": 0.000050272187989256116,
"hadRecentInput": false,
"lastInputTime": 0
}
]

De acuerdo con la métrica personalizada, todavía se produce un cambio de diseño a 3071ms (aproximadamente al mismo tiempo que antes) pero la gravedad del cambio es mucho menor: 0,005%. Puedo vivir con esto.

También está claro en la tira de película que el <h1> La fuente vuelve inmediatamente a una fuente del sistema, lo que permite a los usuarios leerla antes.

Conclusión

Los sitios web complejos probablemente experimentarán muchos más cambios de diseño que en este ejemplo, pero el proceso de corrección sigue siendo el mismo: agregue métricas de inestabilidad de diseño a WebPageTest, haga una referencia cruzada de los resultados con la tira de película de carga visual para identificar los culpables e implemente una solución usando marcadores de posición para reservar el espacio de la pantalla.

(Una cosa más) Medición de la inestabilidad del diseño experimentada por usuarios reales

Es bueno poder ejecutar WebPageTest en una página antes y después de una optimización y ver una mejora en una métrica, pero lo que realmente importa es que la experiencia del usuario está mejorando. ¿No es por eso que estamos tratando de mejorar el sitio en primer lugar?

Entonces, lo que sería genial es si comenzamos a medir las experiencias de inestabilidad de diseño de usuarios reales junto con nuestras métricas tradicionales de rendimiento web. Esta es una pieza crucial del ciclo de retroalimentación de optimización porque tener datos de campo nos dice dónde están los problemas y si nuestras correcciones marcaron una diferencia positiva.

Además de recopilar sus propios datos de inestabilidad de diseño, consulte el Informe de UX de Chrome, que incluye datos de cambio de diseño acumulativo de experiencias de usuarios reales en millones de sitios web. Le permite saber cómo se está desempeñando usted (o sus competidores), o puede usarlo para explorar el estado de inestabilidad del diseño en la web.