Migrar un sitio que ya tenía historia
Cuando una web empresarial se rehace, el contenido antiguo casi nunca desaparece del todo: parte sigue publicado, parte vive en versiones anteriores del sitio y parte solo se conserva en archivos externos. En mavicon.pl, la recuperación de materiales históricos se apoyó en herramientas de importación y exportación y, para lo que ya no estaba en el servidor, en los fondos del Web Archive.
Esa operación tiene una trampa que solo se ve después de publicar. El archivo conserva el texto, pero no conserva las direcciones bajo las cuales ese texto estaba indexado, ni las imágenes que se cargaban desde dominios ajenos. Si no se reconstruyen las direcciones antiguas con redirecciones, la migración parece un éxito y al mismo tiempo borra todo el historial de posiciones en buscadores. El síntoma llega con semanas de retraso, cuando ya nadie relaciona la caída de visitas con una tarea que en su momento se dio por terminada.
Por eso la primera lista del proyecto no fue de funcionalidades, sino de direcciones: qué URL existía antes, qué contenido contenía y a qué dirección nueva le corresponde. Una entrada sin destino claro es una decisión pendiente, no un detalle menor, y es preferible resolverla antes del arranque que descubrirla en un informe de errores seis meses después.
Qué tiene que hacer este sitio por la empresa
Una empresa que vende soluciones técnicas tiene en su web el problema inverso al de una tienda. La tienda enseña producto y precio, y el visitante sabe en segundos si le sirve. Un proveedor de servicios técnicos vende algo que no se puede fotografiar, a un comprador que la mayoría de las veces todavía no sabe nombrar su propio problema. Llega con un síntoma, no con un pedido.
De ahí salen decisiones concretas sobre el contenido. La oferta tiene que poder leerse desde el síntoma y no solo bajo el nombre del servicio, porque quien tiene un sistema de almacén insoportablemente lento no busca la tecnología que habría que sustituir. Los casos prácticos trabajan aquí más que las descripciones de servicio, porque permiten reconocer la propia situación en la de otro. Y el sitio tiene que aguantar la lectura de alguien con criterio técnico que está comprobando si el proveedor sabe de lo que habla; en esa prueba las generalidades suspenden de inmediato y para siempre.
El modelo de contenidos separa por eso tres cosas que en una web corporativa normal viven juntas: la descripción del servicio, la prueba en forma de proyecto entregado y el material explicativo sobre el tema. Cada una tiene un lector distinto, un ritmo de actualización distinto y un lugar distinto en el camino hacia el contacto. Mantenerlas en un solo tipo de contenido ahorra una semana durante la construcción y cuesta durante años, porque a partir de ahí cualquier cambio en una obliga a ir con cuidado con las otras dos.
El objetivo del sitio era construir la imagen de la empresa como especialista, presentar sus casos y captar clientes interesados en servicios avanzados de TI y marketing digital. La disposición y la colocación de los elementos las aportó el cliente, de modo que el trabajo por nuestra parte fue el modelo de contenidos, las plantillas y lo que le ocurre al sitio después del arranque. La implementación llevó alrededor de seis semanas.
Lo que la lista de tecnologías no cuenta
La lista de herramientas describe el sitio tal como está tras años de mantenimiento, no la base con la que se lanzó, y conviene decirlo en voz alta en lugar de dejarlo a la deducción del lector.
El proyecto se puso en marcha en 2012. Eso era WordPress sin REST API en el núcleo, sin editor de bloques, con tipos de contenido personalizados que tenían dos años y con un diseño responsivo que acababa de dejar de ser una novedad. React no se publicó hasta 2013. La REST API llegó al núcleo de WordPress en la versión 4.7, a finales de 2016. Tailwind CSS nació en 2017 y PHP 7 salió en 2015, así que abandonar la rama 5.x fue una tarea de mantenimiento propia, años después del arranque, y no una decisión tomada durante la construcción.
Las descripciones de proyecto presentan de forma rutinaria la capa técnica actual como si fuera la original, y el resultado es que nadie puede distinguir una decisión de diseño de una sustitución posterior impuesta por el paso del tiempo. En un proyecto mantenido durante más de una década, las segundas son más numerosas que las primeras.
Funcionalidades y las decisiones que hay detrás
WordPress con tipos de contenido propios sostiene la separación descrita arriba. Es una decisión que solo se amortiza a los dos años. El primer mes parece complejidad innecesaria, porque las categorías hacen el mismo trabajo. A las doscientas entradas la diferencia es que cambiar la plantilla de los casos no toca el blog, y que quien da de alta un servicio ve un formulario con los campos que un servicio tiene de verdad, en lugar de un campo de texto universal con las instrucciones escritas en un comentario.
El diseño responsivo en 2012 no consistía en añadir clases utilitarias a una plantilla ya hecha. Las rejillas y las reglas responsivas se escribían a mano, y los puntos de ruptura se elegían según el contenido y no según una lista de resoluciones populares. El segundo método parece más razonable y envejece peor, porque la lista de resoluciones populares cambia cada dos años, mientras que el punto en el que una tabla de oferta deja de caber es una propiedad de esa tabla y no cambia nunca.
Los módulos de presentación cargan contenido sin recargar la página. La contrapartida se enuncia poco, así que conviene enunciarla: el contenido que se trae después es contenido que un buscador puede no ver nunca, y en una página cuya única función es generar consultas desde la búsqueda, eso es una decisión comercial y no técnica. La resolución fue que la navegación, el filtrado y las páginas siguientes del listado se cargan de forma asíncrona, mientras que el cuerpo de texto de una página de servicio no lo hace jamás. La primera pantalla está completa en el código fuente del documento.
El formulario de contacto valida en el navegador y en el servidor, y dirige las consultas al departamento correspondiente. La duplicación no sobra. La validación en el navegador existe para que nadie espere una respuesta del servidor solo para enterarse de una errata. La validación en el servidor existe porque la primera se puede saltar, y un formulario sin ella es sencillamente una puerta abierta para robots.
Desafíos de programación
La integración de contenidos dinámicos exigió puntos de acceso propios. Sin REST API en el núcleo de WordPress, eso significó escribir una capa de entrada propia, con su propia comprobación de permisos y su propio formato de respuesta. Es la parte del proyecto que envejeció más rápido, y eso es lo interesante: el código que nace porque la plataforma carecía de algo es el primer candidato a desaparecer el día en que la plataforma lo incorpora. Mantener la solución propia junto al núcleo cuesta después en cada actualización.
El trabajo de rendimiento se apoyó en caché en varias capas con Redis y Memcached, compresión de recursos y distribución mediante CDN. Dos cachés en un mismo proyecto parecen exceso hasta que se ve que atienden cosas distintas: una es caché de objetos para las consultas a la base de datos, la otra guarda sesiones y fragmentos de vistas. Aun así, la ganancia de la caché de objetos en un sitio de marketing es menor de lo que se suele suponer, porque la mayor parte del tráfico son visitantes anónimos en poco más de una decena de páginas, y esas salen más baratas devolviendo la página entera desde caché sin bajar a PHP.
La integración con sistemas externos incluyó intercambio bidireccional con CRM y plataformas de analítica. La decisión determinante fue el comportamiento ante un fallo. Lo habitual en la mayoría de extensiones es mostrar un error o una sección vacía, lo que en una página comercial se lee como una caída del sitio completo. Aquí cada conexión tiene valor de reserva: la última respuesta conocida y, cuando ni esa existe, una variante estática de la sección. El visitante ve una página sin un módulo, no un mensaje de error.
Dónde está en realidad el tiempo de carga
En un sitio corporativo, la conversación sobre velocidad acaba casi siempre en la minificación y la compresión de imágenes, es decir, en el diez por ciento largo que muestra una herramienta de medición. El coste real está en otro sitio y es el mismo en casi cualquier implementación de WordPress de esta clase.
El primer coste es el número de consultas a la base de datos por petición. Un tema que construye el menú, el listado de casos y la sección de servicios relacionados con consultas sueltas dentro de bucles genera decenas donde bastarían tres. En una instalación vacía no se ve nada, porque cada tabla tiene un puñado de registros. Después de dos años de publicar, la diferencia es clara y se manifiesta como lentitud general sin una causa única identificable, que es el peor tipo de problema de rendimiento.
El segundo coste son los recursos que se cargan de forma global. Una extensión de formularios añade por defecto su hoja de estilos y su script a todas las subpáginas, también a las que no tienen formulario. La extensión de galerías hace lo mismo, y la de carruseles también. Sumadas dan unos cuantos cientos de kilobytes que nadie usará nunca, y ninguna parece culpable por separado.
El tercer coste es el menos evidente y tiene que ver con los scripts ajenos. Las herramientas de analítica, los chats y los píxeles publicitarios entran por código pegado en la cabecera y dejan de estar bajo ningún control de versiones. Una avería en el proveedor de uno de esos scripts puede bloquear el renderizado de una página que por lo demás está perfecta, y el diagnóstico empieza por el código propio porque nadie recuerda una línea pegada un año antes.
El orden de los trabajos de rendimiento se deduce de esos tres puntos: primero entregar páginas completas desde caché para el tráfico anónimo, después ordenar las consultas de las vistas que no se pueden cachear, y la compresión de recursos al final. Invertir ese orden da un buen resultado en una prueba sintética y no cambia nada de lo que percibe el visitante.
Mantenimiento del sitio en WordPress
El acompañamiento incluye respuesta a problemas técnicos y corrección de errores tras actualizaciones, actualizaciones periódicas del núcleo, el tema y las extensiones, monitorización de registros, copias de seguridad según calendario y pequeños cambios funcionales y gráficos.
Un punto de esa lista merece desarrollo, porque es el origen de la mayoría de incidentes. Una actualización de extensión rara vez rompe un sitio por sí sola. Lo rompe cuando el tema sobrescribía el comportamiento de esa extensión apoyándose en un detalle de implementación que su autor nunca prometió mantener. Por eso las actualizaciones pasan primero por un entorno de pruebas que es copia de producción y no una instalación limpia. En una instalación nueva con tema predeterminado todo funciona, y esa prueba no dice nada sobre lo que va a ocurrir en el sitio real.
Las copias de seguridad valen algo solo después de que alguien haya restaurado el sitio a partir de una de ellas al menos una vez. Una copia nunca restaurada es una declaración, no una protección, y la diferencia se descubre siempre en el peor momento posible.
Resumen
El sitio mavicon.pl se preparó como herramienta de marketing con una estructura de oferta clara, sitio para los casos prácticos y base para seguir actualizando contenidos. Lo que se transfiere de esta implementación es la forma de trabajar: el modelo de contenidos antes que la plantilla, la reconstrucción de direcciones como parte obligatoria de cualquier migración, las pruebas contra una copia de producción y la separación explícita entre lo que tiene que estar en el código fuente y lo que puede cargarse después.
La pila tecnológica no se transfiere, porque la de 2012 es hoy la mitad distinta, y eso es el curso normal de las cosas y no un defecto del proyecto. La siguiente implementación empieza por un análisis de alcance, y el presupuesto viene después.
Preguntas frecuentes
Respuestas prácticas para aplicar el tema en la ejecución real.
¿Qué alcance tuvo el proyecto mavicon.pl?
#¿Cómo fue la entrega de mavicon.pl?
#¿Qué fue lo más difícil técnicamente en mavicon.pl?
#¿Qué parte de mavicon.pl se puede reutilizar en otro proyecto?
#¿Necesitas un FAQ adaptado a tu sector y mercado? Preparamos una versión alineada con tus objetivos de negocio.
Hablemos