El script GRATUITO de optimización de pagespeed de último recurso
Acelera tu página imposible de arreglar con este método de último recurso para mejorar incluso las páginas más lentas

El script GRATUITO de optimización de pagespeed de último recurso
A veces, como consultor de Core Web Vitals, me encuentro con una página imposible de arreglar. ¡No es que sea imposible de arreglar porque no sepa cómo hacerlo! No, es imposible de arreglar porque solucionarlo significaría reescribir gran parte de un sitio que ya está programado para ser reemplazado. O a veces porque simplemente no hay suficiente acceso y control para mejorar el código del sitio, como ocurre con sistemas CMS más cerrados como WIX, HubSpot, WebFlow, etc. O, por último, cuando simplemente no hay presupuesto. No sucede a menudo, pero a veces los clientes no pueden predecir con precisión la cantidad de trabajo que debe realizarse y pagarse.
Última revisión por Arjen Karel en marzo de 2026
Presentamos "El script de optimización de pagespeed de último recurso"
Cuando te encuentras en este aprieto, este script es tu último intento desesperado por mejorar al menos un poco el pagespeed hasta que puedas construir algo mejor. Funciona inteligentemente usando el Mutation Observer. El script observa cómo el navegador crea el Document Object Model de tu sitio e intercepta y reemplaza inmediatamente el código lento por código más rápido.
Qué hace:
- Intercepta todos los scripts que bloquean el renderizado y los difiere cambiando el tipo del script a type="module". Este truco aprovecha el hecho de que todos los scripts modulares se difieren por defecto. Incluso los scripts en línea. Esto lo convierte en el método más seguro para diferir todos los scripts de la página.
- Carga diferida (lazy loading) de imágenes: se añade loading="lazy" y decoding="async" a todas las imágenes. Esto diferirá la carga de estas imágenes hasta que estén casi en el viewport visible, junto con la actualización asíncrona del diseño de la imagen. Ten cuidado: no querrás cargar de forma diferida tu imagen LCP. Usa la configuración prioImgs para excluirla. Mira por qué el lazy loading en la imagen LCP perjudica el rendimiento.
- Lazy load de iframes. Al igual que con las imágenes, cargar iframes de forma diferida puede priorizar tu propio contenido, ¡que es más importante!
Configuración
El script toma un único "objeto de configuración" y lo usa para omitir el diferimiento o el lazy loading de imágenes y scripts importantes. Para los iframes funciona al revés, solo carga de forma diferida los iframes que coinciden con tu configuración. Todas las configuraciones vienen como una expresión regular. Eso puede sonar aterrador, pero en la práctica es muy simple.
- prioScripts: Omite diferir scripts donde el src coincide con la configuración.
Ejemplo: 'jquery|menu' coincidirá con tu jquery y tu script de menú - prioImgs: Omite el lazy loading para todas las imágenes donde el nombre, la clase o el id de la imagen coincidan.
Ejemplo: 'hero' coincide tanto con <img id="hero" ..> como con <img src="hero.jpg"> - lazyFrames: Solo hace lazy load de los iframes donde el src del iframe coincide con la configuración.
Ejemplo: 'youtube|maps' hace lazy load de todos los iframes de YouTube y Google Maps.
Uso
Limitaciones
Como mencioné anteriormente, realmente no deberías usar este script como tu solución principal para arreglar tu pagespeed. ¡Solo cuando todo lo demás falla, mientras trabajas activamente en un nuevo sitio, es aceptable una solución como esta!
En términos más técnicos, este script compite contra el navegador (y el escáner de precarga), por lo que no se sabe qué elementos lentos ya se habrán activado para su descarga antes de que el script se active.
El script de optimización de pagespeed de último recurso
Aquí tienes una versión minificada que debería usarse en producción
!function(t){['prioScripts', 'prioImgs', 'lazyFrames'].forEach(e=>{t[e]=t[e]?RegExp(t[e],"i"):null});let e=new MutationObserver(e=>{e.forEach(({addedNodes:e})=>{e.forEach(e=>{if(1===e.nodeType)switch(e.tagName){case"SCRIPT":if(!t.prioScripts||!t.prioScripts.test(e.src)){let t=e.getAttribute("type");t&&"text/javascript"!==t||e.setAttribute("type","module")}break;case"IMG":console.log(e.outerHTML),t.prioImgs&&(t.prioImgs.test(e.outerHTML)||e.getAttribute("loading"))||(e.setAttribute("loading","lazy"),e.setAttribute("decoding","async"));break;case"IFRAME":t.lazyFrames.test(e.src)&&e.setAttribute("loading","lazy")}})})});/MSIE|Trident/.test(navigator.userAgent)||(e.observe(document.documentElement,{childList:!0,subtree:!0}),document.addEventListener("DOMContentLoaded",()=>{e.disconnect()}))}({prioScripts:"jquery",prioImgs:"hero",lazyFrames:"youtube|maps"});
Aquí tienes una versión más legible del script. ¡No lo uses en producción! ¡Usa el minificado!
!function (cfg) {\r\n\r\n // Regexify config or nullify\r\n ['prioScripts', 'prioImgs', 'lazyFrames'].forEach((e) => {\r\n cfg[e] = cfg[e] ? new RegExp(cfg[e], "i") : null;\r\n });\r\n\r\n t0 = performance.now();\r\n\r\n /* Watch mutated nodes */\r\n const mutator = new MutationObserver((e) => {\r\n e.forEach(({ addedNodes: e }) => {\r\n e.forEach((e) => {\r\n switch (e.nodeType) {\r\n case 1:\r\n switch (e.tagName) {\r\n // defer scripts by adding type="module", excusive test on src\r\n case "SCRIPT":\r\n if (!cfg.prioScripts || !cfg.prioScripts.test(e.src)) {\r\n let type = e.getAttribute("type");\r\n if (!type || type === "text/javascript") {\r\n e.setAttribute("type", "module");\r\n }\r\n }\r\n break;\r\n\r\n // lazy load images, excusive test on outerHTML for classname, id etc etc\r\n case "IMG":\r\n console.log(e.outerHTML);\r\n if (!cfg.prioImgs || (!cfg.prioImgs.test(e.outerHTML) && !e.getAttribute("loading"))) {\r\n e.setAttribute("loading", "lazy");\r\n e.setAttribute("decoding", "async");\r\n }\r\n break;\r\n\r\n // lazy load iframes, inclusive test on src\r\n case "IFRAME":\r\n if (cfg.lazyFrames.test(e.src)) {\r\n e.setAttribute("loading", "lazy");\r\n }\r\n break;\r\n }\r\n break;\r\n }\r\n });\r\n });\r\n });\r\n\r\n\r\n // Check for IE\r\n if (!/MSIE|Trident/.test(navigator.userAgent)) {\r\n mutator.observe(document.documentElement, { childList: true, subtree: true });\r\n document.addEventListener("DOMContentLoaded", () => {\r\n mutator.disconnect();\r\n console.log("I quit after watching for " + (performance.now() - t0) + " ms");\r\n });\r\n }\r\n}({\r\n prioScripts: 'jquery',\r\n prioImgs: 'hero',\r\n lazyFrames: 'youtube|maps',\r\n});\r\n\r\n\r\n
I have done this before at your scale.
Complex platforms, large dev teams, legacy code. I join your team as a specialist, run the performance track, and hand it back in a state you can maintain.
Discuss Your Situation
