What can your tired old page, once loaded and used and read, can do for your user? It can preload components needed by the next page, so when the users visit the next page, they have the new scripts, styles and images already in the cache. Next page loads faster and the user's happy. On its death bed you tired old page has left a good inheritance for future generations. Good old page.
How can you go about preloading for the next page? By waiting for onload of the current page and requesting the new components. Here are 4 ways to do so, all using a timeout of 1 second after page load so that prefetching doesn't interfere with the user experience on the page.
One way... (DOM)
Using DOM you can create a new LINK element and a new SCRIPT element and append them to the HEAD. For images - it's a one-liner new Image.src="..."
The drawback of this method is that your CSS is executed against the current page and might affect display. Same for JavaScript - it's executed. The image is simply requested and never displayed.
window.onload = function() { setTimeout(function(){ // reference to <head> var head = document.getElementsByTagName('head')[0]; // a new CSS var css = document.createElement('link'); css.type = "text/css"; css.rel = "stylesheet"; css.href = "new.css"; // a new JS var js = document.createElement("script"); js.type = "text/javascript"; js.src = "new.js"; // preload JS and CSS head.appendChild(css); head.appendChild(js); // preload image new Image().src = "new.png"; }, 1000); };
For this way of doing it you can use any JavaScript library's helper methods to load stuff on demand. Good examples - YUI Get and LazyLoad
... or another ... (using iframe)
Another option is to create an iframe and append your components to its head. Using an iframe you can avoid the CSS potentially affecting the current page. JavaScript will still be executed.
window.onload = function() { setTimeout(function(){ // create new iframe var iframe = document.createElement('iframe'); iframe.setAttribute("width", "0"); iframe.setAttribute("height", "0"); iframe.setAttribute("frameborder", "0"); iframe.setAttribute("name", "preload"); iframe.id = "preload"; iframe.src = "about:blank"; document.body.appendChild(iframe); // gymnastics to get reference to the iframe document iframe = document.all ? document.all.preload.contentWindow : window.frames.preload; var doc = iframe.document; doc.open(); doc.writeln("<html><body></body></html>"); doc.close(); // create CSS var css = doc.createElement('link'); css.type = "text/css"; css.rel = "stylesheet"; css.href = "new.css"; // create JS var js = doc.createElement("script"); js.type = "text/javascript"; js.src = "new.js"; // preload CSS and JS doc.body.appendChild(css); doc.body.appendChild(js); // preload IMG new Image().src = "new.png"; }, 1000); };
... I'm gonna find ya ... (static page in iframe)
If your components are static you can create a page that has them all and load that page into the dynamic iframe. Static means knowing them in advance, not relying on page's JavaScript to figure them out on the fly. As you can see, much simpler than the previous code.
window.onload = function() { setTimeout(function(){ // create a new frame and point to the URL of the static // page that has all components to preload var iframe = document.createElement('iframe'); iframe.setAttribute("width", "0"); iframe.setAttribute("height", "0"); iframe.setAttribute("frameborder", "0"); iframe.src = "preloader.html"; document.body.appendChild(iframe); }, 1000); };
... I'm gonna GET
cha, GET
cha, GET
cha! (with Ajax)
Finally - Ajax. Scripts are not executed, CSS not used for rendering. Nice and clean. For simplicty the code has no support for browsers that don't know what XMLHttpRequest is.
window.onload = function() { setTimeout(function(){ // XHR to request a JS and a CSS var xhr = new XMLHttpRequest(); xhr.open('GET', 'new.js'); xhr.send(''); xhr = new XMLHttpRequest(); xhr.open('GET', 'new.css'); xhr.send(''); // preload image new Image().src = "new.png"; }, 1000); };
Thanks!
Any other ways you can think of?
Comments? Find me on BlueSky, Mastodon, LinkedIn, Threads, Twitter