I noticed in the <head>
of my site (for work), there are a lot of <link rel="stylesheet" type="text/css" href="" />
and <script type="text/javascript" src="">
tags. There are even more JavaScript/CSS files that are only loaded for specific pages (we're using CodeIgniter, and the file paths are passed to the header view).
I was considering using a conditional/asynchronous loader (eg. yepnope.js, head.js, etc.), but I noticed a small problem with doing this.
In our views, there is inline JavaScript, some uses $(function(){})
some uses $(document).ready(function(){})
, and some just has code (using jQuery) that's not in a ready
block.
Without editing EVERY view file to wrap its code in a function and calling that when the JS files are loaded, is there a way to delay the inline code until the JavaScript is asynchronously loaded?
You can actually lazyload inline javascript: 1- Change the type parameter in the inline script to: text/delayscript
FROM
<!– Inline Script –>
<script type="text/javascript" language="javaScript">
/* Code */
</script>
To
<!– Inline Script –>
<script type="text/delayscript">
/* Code */
</script>
Giving the script tag a custom Mime type text/delayscript forces the browser to ignore its content (Please note that leaving it out entirely will default to text/javascript).
2- Lazy load all inline scripts Once heads.js (Or an other framework you might be using) confirms that it lazy loaded all your external JS, you can then grab the content of all your custom script tags and inject them in the page:
<script>
head.ready(function() {
var
_head = document.getElementsByTagName("head")[0],
_script = document.createElement('script'),
_scripts = document.getElementsByTagName("script"),
_txt = "text/delayscript",
_contents = []
;
for(var i=0,l=_scripts.length;i<l;i++){
var _type = _scripts[i].getAttribute("type");
if(_type && _type.toLowerCase() ==_txt)
_contents.push(_scripts[i].innerHTML)
}
_script.type = 'text/javascript';
_script.innerHTML = _contents.join(" ");
_head.appendChild(_script);
});
To be even more graceful, you can actually keep the inline scripts in their original hierarchy in the DOM tree instead of jamming all their content in one script, as I have suggested above, by replacing the marked inline script tag by a new one that has mime type text/javascript:
head.ready(function() {
var
_scripts = document.getElementsByTagName("script"),
_doc = document,
_txt = "text/delayscript"
;
for(var i=0,l=_scripts.length;i<l;i++){
var _type = _scripts[i].getAttribute("type");
if(_type && _type.toLowerCase() ==_txt)
_scripts[i].parentNode.replaceChild((function(sB){
var _s = _doc.createElement('script');
_s.type = 'text/javascript';
_s.innerHTML = sB.innerHTML;
return _s;
})(_scripts[i]), _scripts[i]);
}
});
You have to consider moving inline code "outside" and include it with
<script defer="defer" type="text/javascript" src="">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With