Muchos frameworks de frontend dependen de JavaScript para mostrar contenido, por lo que es posible que tardemos 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 software libre disponible en una versión sin interfaz gráfica de Chromium.
¿En qué sitios web podría ser útil el renderizado dinámico?
No todos los robots de los buscadores y redes sociales que visitan tu sitio web pueden ejecutar JavaScript. Por ejemplo, es posible que el robot de Google tarde un poco y que tenga
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 web (especialmente el tiempo que tarda en haber un
primer renderizado importante) puede mejorarse si se utiliza un renderizado híbrido (por ejemplo, el
Angular Universal).
¿Cómo funciona el renderizado dinámico?
El
renderizado dinámico es un proceso mediante el cual se puede pasar del contenido renderizado del cliente al previamente renderizado y viceversa para determinados agentes de usuario.
Deberás tener un procesador para poder ejecutar JavaScript y generar archivos HTML estáticos. Se trata de un proyecto de código abierto que renderiza mediante un
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
Aplicaciones 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.
|
Imágenes de gatitos adorables en cuadrícula y un botón para que aparezcan más: ¡esta aplicación lo tiene todo! |
| |
|
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 su contenido:
En la prueba de optimización para móviles se indica que la página está optimizada para estos dispositivos, pero en la captura de pantalla no aparece ningún gato. Aunque sí aparecen el título y el botón, pero no hay ninguna imagen de gatos.
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
Si quieres mostrar la aplicación web, utiliza
express, una biblioteca 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.
const express = require('express');
const app = express();
const DIST_FOLDER = process.cwd() + '/docs';
const PORT = process.env.PORT || 8080;
// Sirve recursos estáticos (imágenes, css, etc.)
app.get('*.*', express.static(DIST_FOLDER));
// Dirige el resto de las URL a index.html en nuestra aplicación de página única
app.get('*', (req, res) => {
res.sendFile(DIST_FOLDER + '/index.html');
});
// Inicia el servidor Express
app.listen(PORT, () => {
console.log(`Node Express server listening on http://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 express rendertron-middleware
node server.js
A continuación, dirige tu navegador a
http://localhost:8080. Ahora debes 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. Sigue las
recomendaciones del proyecto Rendertron y usa
Google Cloud Platform.
|
Formulario para crear un proyecto de Google Cloud Platform |
Puedes elegir el
nivel gratuito, 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.
1. Crea un proyecto en la
consola de Google Cloud. Consulta el ID del proyecto que aparece bajo del campo de entrada.
2. Instala el
SDK de Google Cloud tal como se describe en el documento e inicia sesión.
3. Clona el repositorio de Rendertron desde GitHub con:
git clone https://github.com/GoogleChrome/rendertron.git
cd rendertron
4. Ejecuta en tu ordenador estos comandos para instalar dependencias y compilar Rendertron:
npm install && npm run build
5. Para activar el caché de Rendertron, crea un archivo llamado config.json en el directorio de Rendertron que incluye el siguiente elemento:
{ "datastoreCache": true }
6. Ejecuta el siguiente comando desde el directorio de Rendertron, pero cambiando ID_DE_TU_PROYECTO por el ID del proyecto del paso 1.
gcloud app deploy app.yaml --project YOUR_PROJECT_ID
7. Selecciona una región, confirma la implementación y espera hasta que finalice.
8. Introduce en tu navegador la URL ID_DE_TU_PROYECTO.appspot.com, pero sustituyendo ID_DE_TU_PROYECTO por el ID de proyecto indicado en el paso 1. A continuación, debería aparecer la interfaz de Rendertron con un campo de entrada y botones.
|
| Interfaz de Rendertron después de la implementación en Google Cloud Platform |
|
Si ves la interfaz web de Rendertron, significa que has implementado correctamente tu propia instancia de Rendertron. Apúntate la URL del proyecto (ID_DE_TU_PROYECTO.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 este comando en el directorio del archivo server.js:
npm install --save rendertron-middleware
Este comando instala el middleware de Rendertron desde npm, por lo que puedes añadirlo al servidor:
const express = require('express');
const app = express();
const rendertron = require('rendertron-middleware');
Configurar la lista de robots
Rendertron utiliza el encabezado HTTP del agente de usuario para determinar si una solicitud proviene de un robot o del navegador de un usuario y lo compara con una
lista actualizada de agentes de usuario de robots. Dado que el robot de Google puede ejecutar JavaSrcipt, 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 agentes de usuario:
const BOTS = rendertron.botUserAgents.concat('googlebot');
const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');
Rendertron compara el encabezado de agente de usuario 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 agente de usuario 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 "ID_DE_TU_PROYECTO" por el ID de tu proyecto de Google Cloud Platform:
app.use(rendertron.makeMiddleware({
proxyUrl: 'https://ID_DE_TU_PROYECTO.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 nuestra 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 toda la página HTML generada por código de JavaScript y se indica que Rendertron deja que JavaScript no muestre 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.
Publicado por Martin Splitt, Unicornio de la Red Abierta