Dynamically including JavaScript & CSS files

When creating JavaScript applications that run from multiple libraries, themes and files, you will hit a common problem.

- Including all of the files in your html page is a huge waste on download speeds and performance (when only half are actually used)

- Including the files when needed improves the download speeds but the users see a lag as they wait for that feature to show

The simplest solution to get around this is to run your feature/theme detection before the html page has loaded and append the additional resources to the page. This means the browser loads them as soon as possible and still gives you the flexibility of running your own logic.

The Google Analytics embed code is a good example which looks something like this:


<script>
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>


However This code inserts the new files before the others in the page. With themes in particular you want to include them after the page files so you can overwrite styles. Here is my modified code for css and js:


<script>
(function() {
var e = document.createElement('link'); e.href = 'css/theme.css'; e.rel = 'stylesheet';
var h = document.getElementsByTagName('head')[0]; h.appendChild(e);
})();
</script>



<script>
(function() {
var f = document.createElement('script'); f.src = 'js/theme.js';
var h = document.getElementsByTagName('head')[0]; h.appendChild(f);
})();
</script>

And if you want to switch the css and js theme based on a url parameter:


<script>
(function() {
var theme = new RegExp('lang=([^&]*)', 'i').exec(window.location.search)[1] || 'default-theme';
var e = document.createElement('link'); e.href = 'css/'+theme+'.css'; e.rel = 'stylesheet';
var f = document.createElement('script'); f.src = 'js/'+theme+'.js';
var h = document.getElementsByTagName('head')[0]; h.appendChild(e); h.appendChild(f);
})();
</script>

No comments:

Post a Comment