Un módulo de pago para PrestaShop que encontramos en la tienda de un cliente cargaba una tipografía decorativa desde una CDN de terceros en todas y cada una de las páginas: la página de inicio, cada categoría, cada producto, el carrito, el checkout. La tipografía se usaba en un único sitio: la propia pantalla de ajustes del módulo, en lo más hondo del back office, donde miraba aproximadamente una persona de toda la empresa.

Esto es lo que ese descuido costó realmente, medido en la página de inicio en producción. El módulo añadía un nuevo dominio de terceros, tres peticiones adicionales por página (una hoja de estilos y dos archivos de tipografía) y unos 159 KB de peso que el navegador de ningún visitante necesitaba. Como la hoja de estilos se situaba en el <head> de la página, bloqueaba el renderizado: cada visitante primerizo esperaba a una resolución DNS y a un handshake TLS con un servidor del que el dueño de la tienda no había oído hablar jamás, antes de que la página pudiera terminar de pintarse. En una conexión móvil limitada, el Largest Contentful Paint pasó de 2,4 a 2,9 segundos y la puntuación de rendimiento de Lighthouse bajó de los 90 y pico a los 80 y medio. No es catastrófico. Es solo un impuesto, aplicado en silencio a cada carga de página, para siempre, por una tipografía que nadie fuera del administrador llegaba a ver.

El radio de impacto era toda la tienda; la funcionalidad era una sola pantalla. Esa brecha —entre lo que un módulo toca y aquello para lo que realmente sirve— es el asunto completo de este artículo. Acotamos el recurso para que la tipografía solo se cargue en la página que la usa, y los números volvieron a su nivel de referencia. La corrección llevó una tarde. Descubrir que estaba ahí solo requirió un navegador y un hábito.

Comparación de rendimiento antes y después de una página de inicio de PrestaShop: un módulo de pago que añadía una tipografía de CDN de terceros aumentaba los dominios de terceros, el peso de la página y el Largest Contentful Paint; acotar el recurso restauró el nivel de referencia

Ese módulo no era malware. Ese es justamente el punto. Nadie intentaba hacer daño a nadie. Un desarrollador quería que su página de ajustes se viera bonita, echó mano de una tipografía y pegó el fragmento de CDN que le daba el sitio web de la tipografía; luego, por ese mismo hábito de copiar y pegar, registró también esa misma hoja de estilos en el hook global de cabecera del front-office, aunque solo la página de ajustes la usaba. Cada decisión era pequeña y razonable de forma aislada. La suma fue una regresión de rendimiento en toda la tienda que ningún «pero si es un módulo pequeño» habría previsto. El descuido bastó. Casi siempre basta.

Si quiere ver lo poco que hace falta, esta es la forma del error —reconstruida, no el código original del proveedor—. La pantalla de ajustes carga esta tipografía perfectamente en el back office; el daño vino de una segunda línea innecesaria que también registraba la misma hoja de estilos en el hook de cabecera del front-office —el que se dispara en cada página de la tienda, donde nada la usa—:

// Runs on EVERY page of the storefront — home, category, product, checkout
public function hookDisplayHeader($params)
{
    // …yet nothing on the storefront uses this font — the settings screen loads it itself.
    $this->context->controller->addCSS(
        'https://3p-cdn.net/fancy-display/style.css'  // third-party, render-blocking
    );
}

Aquí no hay nada malicioso; es un puñado de líneas que hacen exactamente lo que dicen. El problema es que este hook no tiene nada que ver con la pantalla de ajustes para la que es la tipografía. displayHeader se renderiza en la tienda, así que una tipografía pensada para una sola página de administración la descarga cada comprador —para nada—. La corrección consiste en eliminar por completo el registro en la tienda y dejar que el back office siga cargando la tipografía donde de verdad se usa:

// The storefront never shows this font, so the front-office hook loads nothing.
public function hookDisplayHeader($params)
{
    return;
}

// It loads only on this module's own settings screen in the back office —
// self-hosted, so no third-party domain and no extra DNS + TLS round-trip.
public function hookDisplayBackOfficeHeader($params)
{
    if (Tools::getValue('configure') !== $this->name) {
        return; // every other admin page pays nothing either
    }
    $this->context->controller->addCSS($this->_path.'views/css/fancy-display.css');
}

Misma funcionalidad, misma tipografía: la tienda ya no carga nada que no use, y el impuesto que gravaba toda la tienda desaparece junto con el dominio de terceros. Esa brecha entre las dos versiones es toda la diferencia entre un módulo que se mantiene en su carril y otro que, en silencio, cobra a cada página por una funcionalidad que casi nadie ve. Nadie tuvo que ser descuidado a propósito.

El problema es que los módulos fingen ser apps

La mayoría de los comerciantes razonan sobre los módulos igual que razonan sobre las apps del móvil. Una app está aislada en un sandbox: se ejecuta en su propio jardín amurallado, no puede meterse en otras apps y, si no le gusta, la borra y su teléfono queda exactamente como estaba. Ese modelo mental es cómodo y, para PrestaShop, es completamente erróneo.

Un módulo de PrestaShop no es una app aislada en un sandbox. Es PHP sin sandbox que se ejecuta con todos los privilegios de su tienda. Una vez instalado y activado, puede engancharse a cada página que se renderiza, leer y escribir en cualquier tabla de su base de datos —pedidos, clientes, precios, configuración—, registrar overrides que reemplazan en silencio el comportamiento del núcleo, dejar archivos en su plantilla, añadir columnas y tablas, programar tareas en segundo plano y llamar a servicios externos en su nombre. No es un invitado en un jardín amurallado. Es un miembro del personal con las llaves de todo el edificio, y lo contrató haciendo clic en «instalar».

Un módulo no es una funcionalidad que se enciende. Es código al que le da las llaves de su tienda. La pregunta nunca es «¿está bien esta funcionalidad?», sino «¿confío en este código para todo lo que mi tienda puede hacer?».

Nada de eso es un defecto de PrestaShop. Ese poder es precisamente por lo que la plataforma es lo bastante extensible como para sostener un negocio serio. Pero significa que el modelo de seguridad que lleva en la cabeza —el modelo de las apps— no le protege de nada.

Póngalo en concreto: un solo módulo activado puede alcanzar todo esto a la vez: se engancha a cada página que se renderiza, añade y altera tablas de la base de datos, deja archivos de override sobre las clases del núcleo, edita su plantilla, carga recursos en todo el sitio, programa tareas en segundo plano, lee y escribe sus pedidos y registros de clientes, y llama a servicios externos. Una app en su teléfono no puede hacer nada de eso al teléfono. Un módulo de PrestaShop puede hacérselo todo a su tienda, y por eso «instálalo y ya veremos» es una decisión mayor de lo que parece.

Diagrama de lo que un módulo de PrestaShop puede tocar una vez activado: hooks en cada página, tablas de la base de datos, overrides del núcleo, archivos de plantilla, recursos del front-office, tareas cron, datos de pedidos y clientes, y servicios externos

«Funcionaba en mi tienda de pruebas» es donde empiezan los problemas

Las cuatro palabras más caras del desarrollo de módulos son «a mí me funcionaba». Un desarrollador construye un módulo, lo instala en una tienda de pruebas limpia, hace clic por aquí y por allá, ve que funciona y lo publica. El problema es que una tienda de pruebas limpia no se parece en nada a una tienda real.

Su tienda real tiene una plantilla personalizada que sobrescribe plantillas que el módulo daba por sentadas. Puede funcionar en multitienda, donde un módulo que solo se probó contra la tienda 1 se comporta mal en silencio en la tienda 2. Ejecuta una versión de PHP concreta que puede ser más antigua, o más nueva, que la que tenía el desarrollador. Tiene decenas de otros módulos ya enganchados a las mismas páginas, compitiendo por la misma salida. Tiene tráfico real, una capa de caché, un checkout en producción que cobra dinero de verdad y —lo más importante— algún día se actualizará a una nueva versión de PrestaShop contra la que el módulo nunca se probó. «Funcionó una vez, en una tienda, en una versión» no es garantía de nada. Un módulo tiene que seguir funcionando en medio de todo eso, durante años. Esa es una promesa fundamentalmente más difícil que «funciona», y la mayor parte del riesgo vive en esa diferencia. También es la razón por la que la calidad de los módulos importa más que la cantidad de módulos, y es la mitad oculta de qué es lo que realmente ralentiza PrestaShop.

Qué sobrevive cuando desactiva o desinstala

Esta es la creencia que más daño hace: «si causa un problema, lo desinstalo sin más y todo vuelve a la normalidad». A veces es cierto. A menudo no lo es, y merece la pena entender la diferencia con precisión, porque la versión confiada de esta afirmación es como las tiendas acaban rotas en silencio.

Desactivar un módulo detiene el disparo de sus hooks en tiempo de ejecución. Eso ayuda de verdad: el módulo deja de inyectar sus recursos y de ejecutar su código en cada página, así que un problema en vivo de rendimiento o de visualización suele aliviarse de inmediato. Desactivar es el primer movimiento correcto en una emergencia. Pero desactivar no deshace nada de lo que el módulo ya hizo.

Desinstalar va más allá y ejecuta la propia rutina de limpieza del módulo, y esa rutina solo elimina lo que su autor se molestó en escribir código para eliminar. Lo que no vuelve de forma fiable por sí solo:

  • Cambios en la base de datos y la configuración. Pueden quedar atrás tablas nuevas, columnas nuevas y filas de configuración. Algunos módulos conservan sus datos deliberadamente al desinstalar, para que no pierda ajustes en una reinstalación —una decisión razonable, pero solo si se lo dicen—.
  • Datos de pedidos y clientes. Todo lo que se escribió en sus pedidos, facturas o registros de clientes durante el funcionamiento normal son datos reales de su negocio. Desinstalar el módulo no los borra, ni debería hacerlo, pero puede dejarlos en un formato que solo ese módulo entendía.
  • Overrides y ediciones de plantilla. Los archivos dejados en /override o en su plantilla pueden sobrevivir al módulo. Un override obsoleto que queda en su sitio tras la desinstalación es una fuente clásica de «mi tienda se rompió y nada de lo que desactivé lo arregló».
  • Integraciones externas. Los datos que el módulo envió a un servicio de terceros —un feed, un CRM, una plataforma de analítica o de marketing— ya están fuera del control de su tienda. Desinstalar no cambia nada en el otro extremo.

Así que la frase precisa es: desactivar detiene la hemorragia, pero desinstalar no deshace las escrituras en la base de datos, los cambios de configuración, los datos de pedidos y clientes, los overrides, las ediciones de plantilla ni las llamadas externas que un módulo ya realizó. «Ya lo desinstalaré» es un plan para la funcionalidad. No es un plan para la huella que deja.

Ayuda imaginar los tres estados uno al lado del otro. Desactivar detiene la ejecución del módulo. Desinstalar ejecuta su rutina de limpieza. Pero toda una columna de cosas —datos escritos en sus pedidos y clientes, configuración, overrides, ediciones de plantilla y cualquier cosa ya enviada a un servicio externo— sobrevive a ambas, salvo que el autor del módulo escribiera código para revertirlas y usted confirmara que lo hizo. Esa última columna es la que sorprende a la gente en el peor momento posible.

Comparación de lo que elimina desactivar frente a desinstalar un módulo de PrestaShop, y los datos de pedidos, la configuración, los overrides, las ediciones de plantilla y las llamadas externas que sobreviven a ambas

Nosotros también hemos cometido este error

Sería deshonesto escribir todo esto como si solo les pasara a los demás. No es así. Construimos y vendemos módulos de PrestaShop para ganarnos la vida, y hemos cometido el mismo tipo de error.

En uno de nuestros propios módulos, un script del front-office que una única funcionalidad necesitaba quedó registrado en un hook que se dispara en todas las páginas, en lugar de solo en los controladores donde la funcionalidad realmente aparece. Funcionalmente todo iba bien, así que pasó la revisión y se publicó. Fue una auditoría de rendimiento meses después —el mismo tipo de auditoría de este artículo— la que detectó un pequeño script cargándose en todo el sitio sin motivo, en páginas que nunca lo usaban. El coste no fue dramático: unos pocos kilobytes y un poco de tiempo de parseo en cada página, en todo el catálogo, hasta que lo corregimos. Pero era real, era nuestro, y el «funcionaba» lo había dejado pasar sin más.

Lo que cambió no fue un sermón sobre tener más cuidado. Lo convertimos en una pregunta que la revisión tiene que responder para cada recurso y cada hook: ¿esto necesita de verdad ser global, o pertenece a las páginas que lo usan? Una cicatriz se convierte en una regla, y la regla atrapa al siguiente. Esa es la versión honesta de la calidad —no «nunca cometemos errores», sino «construimos lo que los atrapa antes que usted»—. Es la misma disciplina que hay detrás de llevar una tienda real con más de 80 módulos a una puntuación de 99 en PageSpeed: no menos módulos, sino módulos que se mantienen en su carril, que es todo el planteamiento de diseño de nuestra suite Performance Revolution.

Entonces, ¿no es la IA el villano aquí?

Cabría esperar que un proveedor de módulos terminara esto culpando a la IA: código barato generado por IA inundando el mercado de basura. No vamos a hacerlo, porque sería a la vez injusto e hipócrita. Nosotros mismos usamos ingeniería asistida por IA, y mucho. Precisamente por eso no juzgamos un módulo por si una IA lo tocó.

La IA es un acelerador. Hace más rápida la buena ingeniería y hace más rápida la ingeniería descuidada, y no tiene opinión alguna sobre cuál de las dos está haciendo usted. El error de la tipografía en todas las páginas es una década anterior a la ola actual de IA; muchos de ellos los escribió un humano con prisa. Lo que separa un módulo en el que puede confiar de otro en el que no, nunca ha sido las herramientas de su autor. Es la gobernanza: ¿hay un responsable con nombre y apellidos?, ¿se revisa el código?, ¿se prueba?, ¿se mantiene compatible a medida que PrestaShop avanza?, ¿se pueden revertir sus cambios?, ¿se mantiene dentro de su presupuesto de rendimiento?, ¿alguien lo mantendrá el año que viene? Esas preguntas son exactamente igual de válidas tanto si el código lo tecleó una persona, lo generó un modelo o —como ya es normal— lo escribieron juntos una persona y un modelo. La propiedad, la revisión y las pruebas son lo importante. La autoría es una distracción.

Júzguenos con la misma prueba

Nosotros también vendemos módulos, así que sería fácil leer todo esto como «cómprenos a nosotros en su lugar». No se fíe de nuestra palabra: ese es todo el espíritu del asunto. Lo justo es someter a todos los proveedores, nosotros incluidos, al mismo criterio, y la buena noticia es que la mayoría de las comprobaciones importantes no requieren ninguna soltura con PHP. Puede hacerlas desde un navegador en una copia de staging de su tienda: instale el módulo, abra la pestaña de red (Network) de su navegador en su página de inicio (no en la página del módulo) y cuente lo que cambió.

Redactamos el procedimiento completo como una referencia en lenguaje llano —cómo evaluar un módulo de PrestaShop antes de instalarlo en una tienda en producción— y lo pensamos como una herramienta para usar contra nuestro catálogo con la misma facilidad que contra el de cualquiera. Si prefiere que alguien la ejecute por usted, eso es exactamente lo que hacen nuestras auditorías de rendimiento y seguridad, y nuestro análisis de seguridad gratuito es un punto de partida sin coste. Vuelva la lista de comprobación contra nosotros. Preferimos que lo haga.

Preguntas frecuentes

¿Desinstalar un módulo borra todo lo que creó?

No, no de forma fiable. Desinstalar ejecuta la propia rutina de limpieza del módulo, que solo elimina lo que su autor escribió código para eliminar. Las tablas de la base de datos, las filas de configuración, los archivos en /override, las ediciones de plantilla y cualquier dato ya enviado a un servicio externo pueden sobrevivir todos. Tampoco debería borrar nunca sus pedidos ni sus registros de clientes, porque esos son datos reales de su negocio. Dé por sentado que la desinstalación ordena la funcionalidad, no toda la huella.

¿De verdad puede un solo módulo ralentizar toda mi tienda?

Sí. Cuando un módulo carga recursos o ejecuta código en un hook global —uno que se dispara en cada página—, ese coste lo paga cada página, incluidas su página de inicio y su checkout, incluso las páginas donde la funcionalidad nunca aparece. Así es exactamente como una tipografía pensada para una sola pantalla de administración acabó gravando toda una tienda.

¿Un módulo es inseguro solo porque la IA ayudó a escribirlo?

No. La IA es un acelerador, no un veredicto. Lo que hace fiable a un módulo es la propiedad, la revisión, las pruebas, la compatibilidad, la reversibilidad y la disciplina de rendimiento, y eso se aplica tanto si el código lo escribió una persona, un modelo o ambos. Juzgue la gobernanza, no la autoría.

¿Cómo compruebo de verdad un módulo antes de instalarlo?

En una copia de staging, instálelo y observe qué cambia: nuevas peticiones a terceros en la pestaña de red de su página de inicio, nuevas tablas en la base de datos, si el checkout sigue funcionando y si se desinstala limpiamente. Escribimos el paso a paso completo en cómo evaluar un módulo de PrestaShop antes de instalarlo.

Los mejores módulos son aburridos

Después de todas las batallitas, la conclusión es casi anticlimática, y ese es el punto. Un buen módulo es aburrido. Hace la única cosa que anunció. Sus recursos se cargan solo donde se usan. Toca solo los datos que necesita, le dice qué conserva y limpia lo que puede. Sobrevive a su próxima actualización de PrestaShop sin dramas. Y la señal más veraz de su calidad es que, seis meses después de instalarlo, se ha olvidado por completo de que está ahí.

La emoción, en un módulo, es casi siempre el sonido de algo yendo mal en una página que nunca debió tocar. Aburrido es la meta. Aburrido es lo que «simplemente funciona» de verdad parece desde dentro, y merece la pena comprobarlo, a propósito, antes de que un desconocido con las llaves de toda su tienda se instale en ella.

Compartir esta publicación:
David Miller

David Miller

Founder, mypresta.rocks

David Miller es un especialista en PrestaShop con más de una década de experiencia práctica y fundador de mypresta.rocks, un estudio de desarrollo con sede en Tychy, Polonia. Crea y mantiene un catálogo de 152 módulos PrestaShop —incluidas 21 suites «Revolution» que abarcan SEO, checkout, seguridad, rendimiento, marketing, búsqueda, soporte y gestión de almacén— que mejoran tiendas reales cada día, probados en PrestaShop 1.7.8, 8.x y 9.x. También se encarga del mantenimiento de tiendas en producción que facturan millones al año, por lo que su trabajo se mide por ventas reales, no por demos. Su experiencia abarca todo el comercio electrónico —rendimiento, seguridad, SEO y marketing— y va más allá de PrestaShop, hasta WooCommerce, Shopify y sistemas a medida. En el blog escribe sobre la parte técnica de PrestaShop: qué hace realmente la plataforma, qué se rompe en producción y qué soluciones aguantan.

¿Te gustó este artículo?

Recibe nuestros últimos consejos, guías y actualizaciones de módulos en tu bandeja de entrada.

Comentarios

Aún no hay comentarios. ¡Sé el primero!

Sé el primero en hacer una pregunta o compartir una opinión útil.

Cargando...
Volver arriba