The FREE last-ditch effort pagespeed optimization script
Speed up your unfixable page with this last ditch effort method to improve even the slowest pages
The FREE last-ditch effort pagespeed optimization script
Sometimes, as a Core Web Vitals consultant, I come across the unfixable page. It is not that it is unfixable because I do not know how to fix it!
No, it is unfixable because fixing it would mean rewriting large parts of a site that is already scheduled to be replaced Or sometimes when there is just not enough access and control to to improve the site's code as you see with more closed CMS systems like (WIX,HubSpot,WebFlow etc). Or, lastly, when the budget is just not there. It does not happen often yet sometimes clients can not accurately predict the amount of work that needs to be done and paid for.
Introducing "The last-ditch pagespeed optimization script"
When you find yourself in this tight spot, this script is your desperate final attempt to at least improve the pagespeed a little bit until you can build something better. It cleverly works by leveraging the Mutation Observer. The script watches as the Document Object Model of your site is being created by the browser and immediately intercepts and replaces slow code by faster code.
What it does:
- Intercept all render blocking scripts and defer them by changing the type of the script to type="module". This trick makes use of the fact that all modular scripts are deferred by default. Even inline scripts. This makes this the most safe method to defer all page scripts.
- Lazy image loading: loading="lazy" and decoding="async" is added to all images. This will defer the loading of these images until they are almost in the visible viewport along with a asynchronous image layout updating
- Lazy load iframes. Same as with images, lazy loading iframes can prioritize your own, more important, content!
Configuration
The script takes a single 'config object' and uses that config to skips deferring or lazy loading important images and scripts. For iframes it works the other way around, it only lazy loads the iframes that match your config. All configurations come as a regular expression. That may sound scary but in practice it is really simple. Here
- prioScripts: Skips deferring script where the src maches the configuration.
- Example: 'jquery|menu' matches your jquery en your menu script
- prioImgs: Skips lazy loading for all images where the image name, image class or image id matches
Example: 'hero' matches both <img id="hero" ..> and <img src="hero.jpg"> - lazyFrames: LAzy loads only iframes where the iframe src matches the config.
Example: 'youtube|maps' lazy loads all youtube and google maps iframes.
Usage
Limitations
As I previously stated you should really not be using this script as your main solution to fix your pagespeed. Only when all else fails, while you are actively working on a new site, is a solution like this acceptable!
In more technical terms this script races against the browser (and the preload scanner) so there is no telling which slow elements will have already bee triggered for download before the script activates
The last-ditch pagespeed optimization script
Here is a minified version that should be used in production
!function(t){["priorityScripts","priorityImages","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"});
Here is a more readable version of the script. Do not use this in production! Use the minfied one!
!function (cfg) { // Regexify config or nullify ['priorityScripts', 'priorityImages', 'lazyFrames'].forEach((e) => { cfg[e] = cfg[e] ? new RegExp(cfg[e], "i") : null; }); t0 = performance.now(); /* Watch mutated nodes */ const mutator = new MutationObserver((e) => { e.forEach(({ addedNodes: e }) => { e.forEach((e) => { switch (e.nodeType) { case 1: switch (e.tagName) { // defer scripts by adding type="module", excusive test on src case "SCRIPT": if (!cfg.prioScripts || !cfg.prioScripts.test(e.src)) { let type = e.getAttribute("type"); if (!type || type === "text/javascript") { e.setAttribute("type", "module"); } } break; // lazy load images, excusive test on outerHTML for classname, id etc etc case "IMG": console.log(e.outerHTML); if (!cfg.prioImgs || (!cfg.prioImgs.test(e.outerHTML) && !e.getAttribute("loading"))) { e.setAttribute("loading", "lazy"); e.setAttribute("decoding", "async"); } break; // lazy load iframes, inclusive test on src case "IFRAME": if (cfg.lazyFrames.test(e.src)) { e.setAttribute("loading", "lazy"); } break; } break; } }); }); }); // Check for IE if (!/MSIE|Trident/.test(navigator.userAgent)) { mutator.observe(document.documentElement, { childList: true, subtree: true }); document.addEventListener("DOMContentLoaded", () => { mutator.disconnect(); console.log("I quit after watching for " + (performance.now() - t0) + " ms"); }); } }({ prioScripts: 'jquery', prioImgs: 'hero', lazyFrames: 'youtube|maps', });