¿Alguna vez no pudiste usar PageSpeed Insights para probar tus sitios cuando trabajás con desarrollos locales o protecciones de autenticación básica, como las de sitios transferibles de WPEngine y otros entornos protegidos? Esta limitación requiere una solución que te permita aproximar los resultados de PageSpeed Insights con una herramienta que pueda acceder a entornos protegidos.
No poder probar el rendimiento, SEO, accesibilidad y mejores prácticas obstaculiza tu capacidad para optimizar y monitorear eficazmente tu sitio durante el desarrollo.
Para abordar esto, desarrollamos una solución utilizando la herramienta de código abierto de Google, Lighthouse, para realizar auditorías de rendimiento local detalladas bajo condiciones similares a las de PageSpeed Insights.
Con la ayuda de Node.js y Express, utilizaremos Lighthouse para aproximar las auditorías proporcionadas por PageSpeed Insights y ayudarte a optimizar el rendimiento de tu sitio en cada etapa del desarrollo.
¿Por qué necesitamos soluciones de prueba de rendimiento local?
Usar Lighthouse localmente permite a los desarrolladores personalizar el entorno de prueba según sus necesidades específicas, lo cual incluye manejar URLs protegidos por características de autenticación básica. Dado que PageSpeed Insights no puede auditar sitios protegidos, los desarrolladores que quieran optimizar el rendimiento antes del lanzamiento necesitan idear una solución local que ofrezca beneficios similares.
Cómo configurar un entorno de pruebas local con Node.js y Express
Nuestra solución implica configurar un servidor Node.js usando Express para gestionar las solicitudes de pruebas de rendimiento.
Esta configuración te permite aproximar los resultados que obtendrías de PageSpeed Insights y ofrece la flexibilidad para manejar escenarios que la herramienta en línea o el navegador de lighthouse no soportan directamente.
Paso 1: Instalar Node.js y paquetes requeridos
Asegurate de tener Node.js instalado en tu sistema. Luego, creá un nuevo directorio para tu proyecto e instalá los paquetes necesarios:
mkdir lighthouse-server
cd lighthouse-server
npm init -y
npm install express lighthouse chrome-launcher
Paso 2: Configurar el servidor Express
Crea un archivo llamado server.js
y configurá tu servidor Express con el siguiente código:
const express = require('express');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const path = require('path');
const PORT = 3000;
let lighthouse;
let chromeLauncher;
(async () => {
lighthouse = (await import('lighthouse')).default;
chromeLauncher = await import('chrome-launcher');
})();
const app = express();
app.use(express.json());
const resultsDirectory = path.join(__dirname, 'results');
if (!fs.existsSync(resultsDirectory)){
fs.mkdirSync(resultsDirectory, { recursive: true });
}
const getSafeFilename = (url) => {
return encodeURIComponent(url).replace(/[%]/g, '');
}
const loadHistory = (url) => {
const filePath = path.join(resultsDirectory, `${getSafeFilename(url)}.json`);
if (fs.existsSync(filePath)) {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
}
return [];
};
const saveHistory = (url, data) => {
const filePath = path.join(resultsDirectory, `${getSafeFilename(url)}.json`);
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
};
const runLighthouse = async (url, config, outputFilename) => {
const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
const options = {
logLevel: 'info',
output: 'html',
onlyCategories: ['performance', 'accessibility', 'best-practices', 'seo'],
port: chrome.port,
...config,
};
try {
const runnerResult = await lighthouse(url, options);
fs.writeFileSync(outputFilename, runnerResult.report);
return {
scores: {
performance: runnerResult.lhr.categories.performance.score * 100,
accessibility: runnerResult.lhr.categories.accessibility.score * 100,
bestPractices: runnerResult.lhr.categories['best-practices'].score * 100,
seo: runnerResult.lhr.categories.seo.score * 100
},
reportPath: outputFilename
};
} finally {
await chrome.kill();
}
};
app.post('/pagespeed-test', async (req, res) => {
const { url } = req.body;
if (!url) {
return res.status(400).json({ error: 'URL is required' });
}
const id = uuidv4();
const mobileConfig = {
throttling: {
rttMs: 150, // tiempo ida y vuelta en milisegundos
throughputKbps: 1638.4, // rendimiento en kilobits por segundo
cpuSlowdownMultiplier: 4 // cuanto más lento se supone que es el CPU
},
emulatedFormFactor: 'mobile',
channel: 'cli'
};
const desktopConfig = {
throttling: {
rttMs: 40, // tiempo ida y vuelta en milisegundos
throughputKbps: 5000, // rendimiento en kilobits por segundo
cpuSlowdownMultiplier: 1 // sin ralentización
},
emulatedFormFactor: 'desktop',
channel: 'cli'
};
try {
const mobileResults = await runLighthouse(url, mobileConfig, `reports/${id}_mobile.html`);
const desktopResults = await runLighthouse(url, desktopConfig, `reports/${id}_desktop.html`);
const result = {
url,
timestamp: new Date().toISOString(),
mobile: {
scores: mobileResults.scores,
reportUrl: `http://localhost:${PORT}/reports/${id}_mobile.html`
},
desktop: {
scores: desktopResults.scores,
reportUrl: `http://localhost:${PORT}/reports/${id}_desktop.html`
}
};
// Cargar historial existente sin agregar el resultado actual
const history = loadHistory(url);
// Agregar el resultado actual de la prueba al historial para futuras solicitudes
const updatedHistory = [...history, result];
saveHistory(url, updatedHistory);
// Devolver el resultado actual y el historial (excluyendo la prueba actual)
res.json({
currentResult: result,
history: history
});
} catch (error) {
res.status(500).json({ error: 'Error al ejecutar las pruebas de Lighthouse' });
}
});
app.use('/reports', express.static('reports'));
app.listen(PORT, () => {
console.log(`Servidor corriendo en :${PORT}`);
});
Configuraciones
Configuraciones para Móviles
Aceleración. Las pruebas móviles están configuradas con una aceleración significativa en la red y la CPU. La aceleración deliberada simula las condiciones de un dispositivo móvil accediendo al sitio a través de una típica red 3G o 4G, que es más lenta que la mayoría de las conexiones por cable o Wi-Fi.
La aceleración incluye:
- RTT (Round Trip Time). Latencia aumentada para imitar las condiciones de la red.
- Rendimiento. Ancho de banda limitado para reflejar las redes móviles más lentas.
- Ralentización CPU. Simula la menor potencia de procesamiento de los dispositivos móviles comparado con las computadoras de escritorio.
Factor de Forma Emulado. La prueba se realiza en un entorno móvil emulado. Esto significa que el sitio se prueba como aparecería en un dispositivo móvil, considerando factores como el tamaño de pantalla, interfaces táctiles y navegadores móviles.
Configuraciones para Escritorio
Aceleración. Las configuraciones de aceleración para escritorio son menos severas que para móvil, ya que los dispositivos de escritorio generalmente tienen conexiones de red más rápidas y confiables y CPUs más potentes. La aceleración para escritorio podría incluir:
- RTT Mínima. Representa la latencia más baja típicamente experimentada en escritorios.
- Mayor Rendimiento. Refleja las conexiones de Internet más rápidas disponibles para los dispositivos de escritorio.
Factor de Forma Emulado. Sin emulación móvil. Probamos el sitio tal como aparecería en un navegador de escritorio, utilizando todo el espacio de la pantalla y asumiendo métodos de entrada como mouse y teclado.
¿Por qué estamos usando estas configuraciones?
La razón detrás de estas configuraciones específicas es reflejar lo más fielmente posible la experiencia del usuario promedio en cada tipo de dispositivo. Al emular ambientes móviles más lentos y restringidos, podés entender cómo se desempeñará el sitio bajo las condiciones móviles más comunes.
Por otro lado, probar con configuraciones de escritorio permite la evaluación en condiciones óptimas con CPUs más rápidas y velocidades de red más altas.
Este enfoque ayuda a identificar posibles cuellos de botella y problemas de rendimiento que podrían no ser evidentes en un entorno pero son críticos en otro. Por ejemplo, imágenes y scripts pesados que se cargan sin problema en una conexión rápida de escritorio podrían causar demoras significativas en una red móvil.
Paso 3: Ejecutar y probar tu servidor
Ejecutá tu servidor usando:
node server.js
Probá la funcionalidad enviando una solicitud POST a http://localhost:3000/pagespeed-test
con un cuerpo JSON que contenga una URL con autenticación básica embebida.
Si tu sitio tiene autenticación básica, agregá las credenciales de esta forma https://usuario:contraseña@ejemplo.com
.
Descripción revisada de la respuesta
Después de realizar una prueba de Lighthouse mediante nuestra configuración del servidor, la respuesta contiene resultados detallados de rendimiento para configuraciones móviles y de escritorio junto con enlaces a los informes HTML completos. Esto es lo que incluye la respuesta:
- currentResult. Esta sección contiene los resultados de la prueba más reciente, con un desglose para ambos, móvil y escritorio:
- Scores Móviles y de Escritorio: Para cada uno, la respuesta incluye puntuaciones de rendimiento, accesibilidad, mejores prácticas y SEO, cada una escalada a un porcentaje.
- ReportUrl: Enlaces directos a los informes HTML para las pruebas móviles y de escritorio.
- history. Esta parte de la respuesta incluye una lista de resultados de pruebas anteriores para la misma URL, siguiendo la misma estructura que currentResult pero excluyendo la prueba más reciente para proporcionar una vista cronológica de los desempeños pasados.
Ejemplo de la respuesta
Dada la estructura descrita, aquí tenés un ejemplo típico de una respuesta JSON que podrías recibir después de ejecutar una prueba:
{
"currentResult": {
"url": "<https://ejemplo.com>",
"timestamp": "2024-04-24T15:46:01.239Z",
"mobile": {
"scores": {
"performance": 99,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/ac531402-b89e-4bb8-9e07-db3496c3847b_mobile.html>"
},
"desktop": {
"scores": {
"performance": 100,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/ac531402-b89e-4bb8-9e07-db3496c3847b_desktop.html>"
}
},
"history": [
{
"url": "<https://ejemplo.com>",
"timestamp": "2024-04-24T14:53:54.034Z",
"mobile": {
"scores": {
"performance": 100,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/55d65b3b-024f-4acd-92f0-e1928ddd3b95_mobile.html>"
},
"desktop": {
"scores": {
"performance": 100,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/55d65b3b-024f-4acd-92f0-e1928ddd3b95_desktop.html>"
}
},
{
"url": "<https://ejemplo.com>",
"timestamp": "2024-04-24T14:55:07.385Z",
"mobile": {
"scores": {
"performance": 100,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/d1b46f09-3f85-4e7f-98ee-2b2ec0b97afb_mobile.html>"
},
"desktop": {
"scores": {
"performance": 100,
"accessibility": 88,
"bestPractices": 100,
"seo": 90
},
"reportUrl": "<http://localhost:3000/reports/d1b46f09-3f85-4e7f-98ee-2b2ec0b97afb_desktop.html>"
}
}
]
}
Explicación del ejemplo
- currentResult: Muestra las puntuaciones de la prueba más reciente. Proporciona un desglose detallado del rendimiento, accesibilidad, mejores prácticas y puntuaciones de SEO para configuraciones móviles y de escritorio, junto con URLs hacia sus respectivos informes HTML.
- history: Contiene un conjunto de resultados pasados para la misma URL. Cada entrada refleja la estructura de currentResult, documentando la evolución de las métricas del sitio a lo largo del tiempo. Esto es valioso para rastrear mejoras o regresiones tras actualizaciones u optimizaciones.
Este formato de respuesta integral permite a los desarrolladores obtener rápidamente una visión general de las últimas métricas de rendimiento del sitio al tiempo que mantienen un registro histórico para análisis de tendencias y seguimiento de rendimiento a largo plazo.
Probar rendimiento en entornos protegidos con Lighthouse
Al aprovechar la potencia de Lighthouse, Node.js y Express, podemos crear un entorno de prueba robusto para aproximar las capacidades de PageSpeed Insights de Google mientras ofrecemos funciones adicionales adaptadas a las necesidades de los desarrolladores que trabajan en entornos de desarrollo seguros o restringidos.
Este método mejora tu capacidad para optimizar el rendimiento del sitio y asegura que tu experiencia de prueba sea lo más cercana posible a tu entorno en vivo.
Si encontraste útil este post, leé nuestro blog y recursos para desarrolladores para más ideas y guías!