Jueves, 31 de enero del 2019
Muchos frameworks de frontend dependen de JavaScript para mostrar contenido, por lo que es posible que Google tarde un poco en indexar tu contenido o en actualizar el contenido indexado.
Este año en Google I/O hemos hablado sobre una posible solución: el renderizado dinámico. Hay muchas formas de implementarla, pero la que tratamos en esta entrada de blog es mediante Rendertron, un proyecto de código abierto disponible en una versión sin interfaz gráfica de Chromium.
¿En qué sitios podría ser útil el renderizado dinámico?
No todos los robots de los buscadores y las redes sociales que visitan tu sitio web pueden ejecutar JavaScript. Por ejemplo, el robot de Google puede tardar un tiempo en ejecutar el código JavaScript y tiene algunas limitaciones.
Resulta útil emplear renderizado dinámico con contenido que cambia con frecuencia y necesita JavaScript para mostrarse. La experiencia de usuario de tu sitio (especialmente el tiempo que tarda el primer renderizado significativo) puede mejorarse si se utiliza un renderizado híbrido (por ejemplo, Angular Universal).
¿Cómo funciona el renderizado dinámico?
Renderizado dinámico significa cambiar entre renderizar el contenido en el cliente y renderizarlo previamente según el user-agent.
Deberás tener un procesador para poder ejecutar JavaScript y generar archivos HTML estáticos. Rendertron es un proyecto de código abierto que renderiza mediante una versión de Chromium sin interfaz gráfica. Las aplicaciones de página única suelen cargar datos en segundo plano o retrasar su carga para renderizar su contenido. Rendertron tiene mecanismos que determinan si se ha completado el renderizado de un sitio web y espera hasta que todas las solicitudes de red hayan finalizado y no haya ningún proceso pendiente.
Esta entrada se divide en los siguientes temas:
- Aplicación web de muestra
- Configuración de un servidor
express.js
básico que sirva la aplicación web - Instalación y configuración de Rendertron como middleware para aplicar renderizado dinámico
Aplicación web de muestra
La aplicación web Kitten Corner usa JavaScript para cargar varias imágenes de gatos de una API y las muestra en una cuadrícula.
Así se representa el JavaScript:
const apiUrl = 'https://api.thecatapi.com/v1/images/search?limit=50'; const tpl = document.querySelector('template').content; const container = document.querySelector('ul'); function init () { fetch(apiUrl) .then(response => response.json()) .then(cats => { container.innerHTML = ''; cats .map(cat => { const li = document.importNode(tpl, true); li.querySelector('img').src = cat.url; return li; }).forEach(li => container.appendChild(li)); }) } init(); document.querySelector('button').addEventListener('click', init);
La aplicación web usa un tipo de JavaScript reciente (ES6) que todavía no es compatible con el robot de Google. Con la prueba de optimización para móviles se puede comprobar si el robot de Google puede ver el contenido:
Si bien este problema es fácil de solucionar, es útil saber cómo se configura el renderizado dinámico, puesto que permitirá que el robot de Google vea las imágenes de gatos sin que tengas que editar el código de la aplicación web.
Configurar el servidor
Para servir la aplicación web, utilizaremos express
, una biblioteca de node.js
, para compilar servidores web.
El código del servidor tiene una estructura similar a la que aparece a continuación. Si quieres, consulta el código fuente completo del proyecto aquí.
const express = require('express'); const app = express(); const DIST_FOLDER = process.cwd() + '/docs'; const PORT = process.env.PORT || 8080; // Serve static assets (images, css, etc.) app.get('*.*', express.static(DIST_FOLDER)); // Point all other URLs to index.html for our single page app app.get('*', (req, res) => { res.sendFile(DIST_FOLDER + '/index.html'); }); // Start Express Server app.listen(PORT, () => { console.log(`Node Express server listening on https://localhost:${PORT} from ${DIST_FOLDER}`); });
Puedes probar este ejemplo: si usas un navegador moderno, deberías ver muchas imágenes de gatos. Para ejecutar el proyecto desde el ordenador, deberás tener node.js
para ejecutar estos comandos:
npm install --save express rendertron-middleware node server.js
A continuación, dirige tu navegador a https://localhost:8080
.
Ahora es el momento de configurar el renderizado dinámico.
Implementar una instancia de Rendertron
Rendertron ejecuta un servidor que toma una URL y devuelve un archivo HTML estático de la URL mediante el navegador Chromium sin interfaz gráfica. Seguiremos las recomendaciones del proyecto Rendertron y usaremos Google Cloud Platform.
Puedes empezar con el nivel de uso disponible sin pago, pero debes tener en cuenta que, si te decantas por esta opción, usar aplicaciones de producción puede conllevar costes tal como se indica en los precios de Google Cloud Platform.
- Crea un proyecto en la consola de Google Cloud. Anota el "ID del proyecto" que aparece debajo del campo de entrada.
- Instala el SDK de Google Cloud tal como se describe en la documentación e inicia sesión.
-
Clona el repositorio de Rendertron desde GitHub con:
git clone https://github.com/GoogleChrome/rendertron.git cd rendertron
-
Ejecuta en tu ordenador estos comandos para instalar dependencias y compilar Rendertron:
npm install && npm run build
-
Para habilitar la caché de Rendertron, crea un archivo llamado
config.json
en el directorio de Rendertron con el siguiente elemento:{ "datastoreCache": true }
-
Ejecuta el siguiente comando desde el directorio de Rendertron, pero cambiando
YOUR_PROJECT_ID
por el ID del proyecto del paso 1.gcloud app deploy app.yaml --project YOUR_PROJECT_ID
- Selecciona una zona geográfica, confirma la implementación y espera hasta que finalice.
- Escribe la URL
YOUR_PROJECT_ID.appspot.com
. A continuación, debería aparecer la interfaz de Rendertron con un campo de entrada y algunos botones.
Si ves la interfaz web de Rendertron, significa que has implementado correctamente tu propia instancia de Rendertron. Anota la URL de tu proyecto (YOUR_PROJECT_ID.appspot.com
), ya que la necesitarás en la siguiente fase del proceso.
Añadir Rendertron al servidor
El servidor web utiliza express.js
y Rendertron tiene un middleware express.js
. Ejecuta el siguiente comando en el directorio del archivo server.js
:
npm install --save rendertron-middleware
Este comando instala el middleware de Rendertron desde npm para que podamos añadirlo al servidor:
const express = require('express'); const app = express(); const rendertron = require('rendertron-middleware');
Configurar la lista de robots
Rendertron usa el encabezado HTTP user-agent
para determinar si una solicitud procede de un robot o del navegador de un usuario y lo compara con una lista actualizada de user-agents de robots. Dado que el robot de Google puede ejecutar JavaScript, la lista no incluye el robot de Google de manera predeterminada. Para que Rendertron también procese las solicitudes del robot de Google, añádelo a la lista de user-agents:
const BOTS = rendertron.botUserAgents.concat('googlebot'); const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');
Rendertron compara el encabezado user-agent
con esta expresión regular más adelante.
Añadir el middleware
Para enviar solicitudes de robots a la instancia de Rendertron, su middleware debe estar incluido en nuestro servidor express.js
. El middleware comprueba el user-agent que está haciendo las solicitudes y reenvía las de robots conocidos a la instancia de Rendertron. Añade el siguiente fragmento de código a server.js, cambiando YOUR_PROJECT_ID
por el ID de tu proyecto de Google Cloud Platform:
app.use(rendertron.makeMiddleware({ proxyUrl: 'https://YOUR_PROJECT_ID.appspot.com/render', userAgentPattern: BOT_UA_PATTERN }));
Los robots que solicitan el sitio web de muestra reciben el archivo HTML estático de Rendertron, por lo que no hace falta que ejecuten JavaScript para mostrar el contenido.
Probar la configuración
Para probar si la configuración de Rendertron se ha hecho correctamente, vuelve a ejecutar la prueba de optimización para móviles.
A diferencia de lo que pasaba en la primera prueba, ahora aparecen las imágenes de gatos. En la pestaña HTML se muestra todo el HTML generado por código de JavaScript y se indica que Rendertron ha eliminado la necesidad de ejecutar JavaScript para mostrar el contenido.
Conclusión
Has creado una configuración de renderizado dinámico sin editar la aplicación web. Con estos cambios, puedes servir una versión HTML estática de la aplicación web a los rastreadores.