Estrategias y mejores prácticas de React SEO

Publicado: 2022-03-11

React fue desarrollado para crear interfaces de usuario interactivas declarativas , modulares y multiplataforma . Hoy en día, es uno de los marcos de JavaScript más populares, si no el más popular, para escribir aplicaciones front-end de alto rendimiento. Desarrollado inicialmente para escribir aplicaciones de una sola página (SPA), React ahora se usa para crear sitios web completos y aplicaciones móviles.

Si tiene una amplia experiencia en el desarrollo web convencional y cambia a React, notará que una cantidad cada vez mayor de su código HTML y CSS se traslada a JavaScript. Esto se debe a que React no recomienda crear o actualizar elementos de la interfaz de usuario directamente, sino describir el "estado" de la interfaz de usuario. React luego actualizará el DOM para que coincida con el estado de la manera más eficiente.

Como resultado, todos los cambios en la interfaz de usuario o el DOM deben realizarse a través del motor de React. Aunque es conveniente para los desarrolladores, esto puede significar tiempos de carga más prolongados para los usuarios y más trabajo para que los motores de búsqueda encuentren e indexen el contenido.

En este artículo, abordaremos los desafíos que enfrentamos al crear aplicaciones y sitios web React con rendimiento SEO, y describiremos varias estrategias utilizadas para superarlos.

Cómo rastrea e indexa Google las páginas web

Google recibe más del 90% de todas las búsquedas en línea. Echemos un vistazo más de cerca a su proceso de rastreo e indexación.

Esta instantánea tomada de la documentación de Google puede ayudarnos. Tenga en cuenta que este es un diagrama de bloques simplificado. El Googlebot real es mucho más sofisticado.

Diagrama de Googlebot indexando un sitio web.

Puntos a tener en cuenta:

  1. Googlebot mantiene una cola de rastreo que contiene todas las URL que necesita rastrear e indexar en el futuro.
  2. Cuando el rastreador está inactivo, selecciona la siguiente URL en la cola, realiza una solicitud y obtiene el HTML.
  3. Después de analizar el HTML, Googlebot determina si necesita obtener y ejecutar JavaScript para representar el contenido. En caso afirmativo, la URL se agrega a una cola de procesamiento.
  4. En un momento posterior, el renderizador busca y ejecuta JavaScript para renderizar la página. Envía el HTML renderizado de vuelta a la unidad de procesamiento.
  5. La unidad de procesamiento extrae todas las <a> tags mencionadas en la página web y las vuelve a agregar a la cola de rastreo.
  6. El contenido se agrega al índice de Google.

Tenga en cuenta que existe una clara distinción entre la etapa de procesamiento que analiza HTML y la etapa de procesamiento que ejecuta JavaScript.

Esta distinción existe porque la ejecución de JavaScript es costosa , dado que los robots de Google necesitan ver más de 130 billones de páginas web. Entonces, cuando Googlebot rastrea una página web, analiza el HTML inmediatamente y luego pone en cola el JavaScript para ejecutarlo más tarde. La documentación de Google menciona que una página permanece en la cola de procesamiento durante unos segundos, aunque puede ser más.

También vale la pena mencionar el concepto de presupuesto de rastreo. El rastreo de Google está limitado por el ancho de banda, el tiempo y la disponibilidad de las instancias de Googlebot. Asigna un presupuesto o recursos específicos para indexar cada sitio web. Si está creando un sitio web grande con mucho contenido con miles de páginas (por ejemplo, un sitio web de comercio electrónico) y estas páginas usan mucho JavaScript para representar el contenido, es posible que Google pueda leer menos contenido de su sitio web.

Nota: Puede leer las pautas de Google para administrar su presupuesto de rastreo aquí.

Por qué optimizar React para SEO es un desafío

Nuestra breve descripción general de Googlebot, el rastreo y la indexación solo araña la superficie. Sin embargo, los ingenieros de software deben identificar los problemas potenciales que enfrentan los motores de búsqueda que intentan rastrear e indexar las páginas de React. Ahora podemos echar un vistazo más de cerca a lo que hace que React SEO sea un desafío y lo que los desarrolladores pueden hacer para abordar y superar algunos de estos desafíos.

Contenido de primer paso vacío

Sabemos que las aplicaciones React dependen en gran medida de JavaScript y, a menudo, tienen problemas con los motores de búsqueda. Esto se debe a que React emplea un modelo de shell de aplicación de forma predeterminada. El HTML inicial no contiene ningún contenido significativo y un usuario o un bot debe ejecutar JavaScript para ver el contenido real de la página.

Este enfoque significa que Googlebot detecta una página vacía durante la primera pasada. Google ve el contenido solo cuando se representa la página. Esto retrasará la indexación del contenido cuando se trate de miles de páginas.

Tiempo de carga y experiencia de usuario

Obtener, analizar y ejecutar JavaScript lleva tiempo. Además, es posible que JavaScript deba realizar llamadas de red para obtener el contenido, y es posible que el usuario deba esperar un tiempo antes de poder ver la información solicitada.

Google ha presentado un conjunto de elementos vitales web relacionados con la experiencia del usuario, que se utilizan en sus criterios de clasificación. Un tiempo de carga más largo puede afectar el puntaje de la experiencia del usuario, lo que lleva a Google a clasificar un sitio más bajo.

Revisamos el rendimiento del sitio web en detalle en la siguiente sección.

Metadatos de página

Las etiquetas <meta> son útiles porque permiten que Google y otros sitios web de redes sociales muestren títulos, miniaturas y descripciones apropiados para las páginas. Pero estos sitios web se basan en la etiqueta <head> de la página web obtenida para obtener esta información. Estos sitios web no ejecutan JavaScript para la página de destino.

React muestra todo el contenido, incluidas las metaetiquetas, en el cliente. Dado que el shell de la aplicación es el mismo para todo el sitio web/aplicación, puede ser difícil adaptar los metadatos para páginas individuales.

mapa del sitio

Un mapa del sitio es un archivo en el que proporciona información sobre las páginas, videos y otros archivos en su sitio y las relaciones entre ellos. Los motores de búsqueda como Google leen este archivo para rastrear su sitio de manera más inteligente.

React no tiene una forma integrada de generar mapas de sitio. Si está utilizando algo como React Router para manejar el enrutamiento, puede encontrar herramientas que pueden generar un mapa del sitio, aunque puede requerir un poco de esfuerzo.

Otras consideraciones de SEO

Estas consideraciones están relacionadas con el establecimiento de buenas prácticas de SEO en general.

  1. Tenga una estructura de URL óptima para que los humanos y los motores de búsqueda tengan una buena idea de qué esperar en la página.
  2. La optimización del archivo robots.txt puede ayudar a los robots de búsqueda a comprender cómo rastrear las páginas de su sitio web.
  3. Use un CDN para servir todos los activos estáticos como CSS, JS, fuentes, etc. y use imágenes receptivas para reducir los tiempos de carga.

Podemos abordar muchos de los problemas descritos anteriormente utilizando la representación del lado del servidor (SSR) o la representación previa. Revisaremos estos enfoques a continuación.

Ingrese reacción isomorfa

La definición del diccionario de isomorfo es "correspondiente o similar en forma".

En términos de React, esto significa que el servidor tiene una forma similar a la del cliente. En otras palabras, puede reutilizar los mismos componentes de React en el servidor y el cliente.

Este enfoque isomorfo permite que el servidor renderice la aplicación React y envíe la versión renderizada a nuestros usuarios y motores de búsqueda para que puedan ver el contenido al instante mientras JavaScript se carga y ejecuta en segundo plano.

Frameworks como Next.js o Gatsby han popularizado este enfoque. Debemos tener en cuenta que los componentes isomorfos pueden verse sustancialmente diferentes a los componentes React convencionales. Por ejemplo, pueden incluir código que se ejecuta en el servidor en lugar del cliente. Incluso pueden incluir secretos de API (aunque el código del servidor se elimina antes de enviarlo al cliente).

Un punto a tener en cuenta es que estos marcos abstraen mucha complejidad pero también introducen una forma obstinada de escribir código. Profundizaremos en las compensaciones de rendimiento en este artículo.

También haremos un análisis matricial para comprender la relación entre las rutas de procesamiento y el rendimiento del sitio web. Pero antes de eso, repasemos algunos conceptos básicos para medir el rendimiento del sitio web.

Métricas para el rendimiento del sitio web

Examinemos algunos de los factores que utilizan los motores de búsqueda para clasificar los sitios web.

Además de responder a la consulta de un usuario de forma rápida y precisa, Google cree que un buen sitio web debe tener los siguientes atributos:

  • Debería cargarse rápidamente.
  • Los usuarios deberían poder acceder al contenido sin demasiado tiempo de espera.
  • Debería volverse interactivo para las acciones de un usuario desde el principio.
  • No debe obtener datos innecesarios ni ejecutar código costoso para evitar agotar los datos o la batería de un usuario.

Estas características se corresponden aproximadamente con las siguientes métricas:

  • TTFB : Tiempo hasta el primer byte: el tiempo entre hacer clic en un enlace y la entrada del primer bit de contenido.
  • LCP : mayor pintura con contenido: el momento en que el artículo solicitado se vuelve visible. Google recomienda mantener este valor por debajo de los 2,5 segundos.
  • TTI : Time To Interactive: el momento en que una página se vuelve interactiva (un usuario puede desplazarse, hacer clic, etc.).
  • Tamaño del paquete: la cantidad total de bytes descargados y el código ejecutado antes de que la página se vuelva completamente visible e interactiva.

Revisaremos estas métricas para comprender mejor cómo las distintas rutas de representación pueden afectar a cada una de ellas.

A continuación, comprendamos las diferentes rutas de renderización disponibles para los desarrolladores de React.

Rutas de renderizado

Podemos renderizar una aplicación React en el navegador o en el servidor y producir diferentes resultados.

Dos funciones cambian significativamente entre las aplicaciones renderizadas del lado del cliente y del servidor, a saber, el enrutamiento y la división de código . Echamos un vistazo más de cerca a estos a continuación.

Representación del lado del cliente (CSR)

La representación del lado del cliente es la ruta de representación predeterminada para un React SPA. El servidor servirá una aplicación de shell que no contiene ningún contenido. Una vez que el navegador descarga, analiza y ejecuta las fuentes de JavaScript incluidas, el contenido HTML se completa o representa .

La función de enrutamiento es manejada por la aplicación cliente al administrar el historial del navegador. Esto significa que se sirve el mismo archivo HTML independientemente de la ruta solicitada, y el cliente actualiza su estado de vista después de que se representa.

La división de código es relativamente sencilla. Puede dividir su código mediante importaciones dinámicas o React.lazy de modo que solo se carguen las dependencias necesarias según la ruta o las acciones del usuario.

Si la página necesita obtener datos del servidor para generar contenido (por ejemplo, el título de un blog o la descripción de un producto), solo puede hacerlo cuando los componentes relevantes están montados y procesados.

Lo más probable es que el usuario vea un signo o indicador de "Cargando datos" mientras el sitio web obtiene datos adicionales.

Representación del lado del cliente con datos de arranque (CSRB)

Considere el mismo escenario que CSR pero en lugar de obtener datos después de que se represente el DOM, digamos que el servidor envió datos relevantes arrancados dentro del HTML servido.

Podríamos incluir un nodo que se vea así:

 <script type="application/json"> {"title": "My blog title", "comments":["comment 1","comment 2"]} </script>

Y analícelo cuando el componente se monte:

 var data = JSON.parse(document.getElementById('data').innerHTML);

Nos acabamos de ahorrar un viaje de ida y vuelta al servidor. Veremos las compensaciones en un momento.

Representación del lado del servidor a contenido estático (SSRS)

Imagine un escenario en el que necesitamos generar HTML sobre la marcha.

Por ejemplo, si estamos construyendo una calculadora en línea y el usuario emite una consulta del tipo /calculate/34+15 (omitiendo el escape de URL). Necesitamos procesar la consulta, evaluar el resultado y responder con HTML generado.

Nuestro HTML generado tiene una estructura bastante simple y no necesitamos React para administrar y manipular el DOM una vez que se sirve el HTML generado.

Así que solo estamos sirviendo contenido HTML y CSS. Puede usar el método renderToStaticMarkup para lograr esto.

El servidor manejará completamente el enrutamiento, ya que necesita volver a calcular HTML para cada resultado, aunque el almacenamiento en caché de CDN se puede usar para entregar respuestas más rápido. El navegador también puede almacenar en caché los archivos CSS para cargas de página posteriores más rápidas.

Representación del lado del servidor con rehidratación (SSRH)

Imagine el mismo escenario que el descrito anteriormente, pero esta vez necesitamos una aplicación React completamente funcional en el cliente.

Vamos a realizar el primer renderizado en el servidor y devolver el contenido HTML junto con los archivos JavaScript. React rehidratará el marcado generado por el servidor y la aplicación se comportará como una aplicación CSR a partir de este momento.

React proporciona métodos integrados para realizar estas acciones.

La primera solicitud es manejada por el servidor y los renderizados subsiguientes son manejados por el cliente. Por lo tanto, dichas aplicaciones se denominan aplicaciones React universales (representadas tanto en el servidor como en el cliente). El código para manejar el enrutamiento se puede dividir (o duplicar) en el cliente y el servidor.

La división de código también es un poco complicada ya que ReactDOMServer no es compatible con React. perezoso, por lo que es posible que deba usar algo como Componentes cargables.

También se debe tener en cuenta que ReactDOMServer solo realiza un renderizado superficial. En otras palabras, aunque se invocará el método de procesamiento de sus componentes, no se llamará a los métodos de ciclo de vida como componentDidMount . Por lo tanto, deberá refactorizar su código para proporcionar datos a sus componentes utilizando un método alternativo.

Aquí es donde aparecen frameworks como NextJS. Enmascaran las complejidades asociadas con el enrutamiento y la división de código en SSRH y brindan una experiencia de desarrollador más fluida.

Este enfoque produce resultados mixtos en lo que respecta al rendimiento de la página, como veremos en un momento.

Renderizado previo a contenido estático (PRS)

¿Qué pasaría si pudiéramos renderizar una página web antes de que un usuario la solicite? Esto podría hacerse en el momento de la compilación o dinámicamente cuando cambien los datos.

Luego podemos almacenar en caché el contenido HTML resultante en un CDN y servirlo mucho más rápido cuando un usuario lo solicite.

Esto se denomina procesamiento previo antes de procesar el contenido, solicitud previa del usuario. Este enfoque se puede utilizar para blogs y aplicaciones de comercio electrónico, ya que su contenido normalmente no depende de los datos proporcionados por el usuario.

Renderizado previo con rehidratación (PRH)

Es posible que queramos que nuestro HTML renderizado previamente sea una aplicación React completamente funcional cuando un cliente la renderice.

Después de atender la primera solicitud, la aplicación se comportará como una aplicación React estándar. Este modo es similar a SSRH, descrito anteriormente, en términos de funciones de enrutamiento y división de código.

Matriz de rendimiento

El momento que has estado esperando por fin ha llegado. Es hora de un enfrentamiento. Veamos cómo cada una de estas rutas de representación afecta las métricas de rendimiento web y determinemos el ganador.

En esta matriz, asignamos una puntuación a cada ruta de renderizado en función de su rendimiento en una métrica de rendimiento.

La puntuación va del 1 al 5:

  • 1 = Insatisfactorio
  • 2 = Pobre
  • 3 = Moderado
  • 4 = Bueno
  • 5 = Excelente
TTFB
Tiempo hasta el primer byte
LCP
Pintura con contenido más grande
ITT
Tiempo para interactivo
Tamaño del paquete
Total
RSE 5
HTML se puede almacenar en caché en un CDN
1
Múltiples viajes al servidor para obtener HTML y datos
2
Obtención de datos + retrasos en la ejecución de JS
2
Todas las dependencias de JS deben cargarse antes de renderizar
10
CSRB 4
HTML puede almacenarse en caché dado que no depende de los datos de solicitud
3
Los datos se cargan con la aplicación.
3
JS debe obtenerse, analizarse y ejecutarse antes de que sea interactivo
2
Todas las dependencias de JS deben cargarse antes de renderizar
12
SSRS 3
HTML se genera en cada solicitud y no se almacena en caché
5
Sin carga útil de JS ni operaciones asíncronas
5
La página es interactiva inmediatamente después de la primera pintura
5
Contiene solo contenido estático esencial
18
SSRH 3
HTML se genera en cada solicitud y no se almacena en caché
4
El primer renderizado será más rápido porque el servidor renderizó el primer pase
2
Más lento porque JS necesita hidratar DOM después del primer análisis HTML + pintura
1
Las dependencias renderizadas de HTML + JS deben descargarse
10
PRS 5
HTML se almacena en caché en un CDN
5
Sin carga útil de JS ni operaciones asíncronas
5
La página es interactiva inmediatamente después de la primera pintura
5
Contiene solo contenido estático esencial
20
PRH 5
HTML se almacena en caché en un CDN
4
El primer renderizado será más rápido porque el servidor renderizó el primer pase
2
Más lento porque JS necesita hidratar DOM después del primer análisis HTML + pintura
1
Las dependencias renderizadas de HTML + JS deben descargarse
12

Conclusiones clave

La renderización previa al contenido estático (PRS) conduce a sitios web de mayor rendimiento , mientras que la renderización del lado del servidor con hidratación (SSRH) o la renderización del lado del cliente (CSR) puede generar resultados decepcionantes.

También es posible adoptar múltiples enfoques para diferentes partes del sitio web . Por ejemplo, estas métricas de rendimiento pueden ser fundamentales para las páginas web públicas, ya que pueden indexarse ​​de manera más eficiente, mientras que pueden ser menos importantes una vez que un usuario ha iniciado sesión y ve los datos de la cuenta privada.

Cada ruta de procesamiento representa compensaciones en dónde y cómo desea procesar sus datos. Lo importante es que un equipo de ingeniería pueda ver y discutir claramente estas compensaciones y elegir una arquitectura que maximice la felicidad de sus usuarios.

Lecturas adicionales y consideraciones

Si bien traté de cubrir las técnicas actualmente populares, este no es un análisis exhaustivo. Recomiendo encarecidamente leer este artículo donde los desarrolladores de Google analizan otras técnicas avanzadas como la representación del servidor de transmisión, la representación trisomórfica y la representación dinámica (que ofrece diferentes respuestas a los rastreadores y usuarios).

Algunos otros factores que debe considerar al crear sitios web con mucho contenido incluyen la necesidad de un buen sistema de administración de contenido (CMS) para sus autores y la capacidad de generar/modificar fácilmente vistas previas de redes sociales y optimizar imágenes para diferentes tamaños de pantalla.