I've bumped into an issue with this a few times recently on pages I've been looking at so I figured it was worth warning everyone to avoid this:
That little bit of inline javascript causes the browser to not load the external js at the same time as the css because it needs to block to execute the code.<link rel="stylesheet" type="text/css" href="my.css" /> <script type="text/javascript"> var1='some value'; var2=true; </script> <script type="text/javascript" src="my.js"></script>
Thanks to Steve's handy Cuzillion app I threw together a quick page with exactly that structure and this is how it loads:
Move the inline javascript up above the css
As long as the javascript isn't going to be modifying the css, you'll be a lot better off moving the inline code up above the css so it can execute without having to block anything else. If you're just setting variables for later javascript to use then this is a no-brainer.
Here is what it looks like with the inline javascript moved up above the css:
The javascript is back where it should be, loading in parallel to the css.
Patrick,
ReplyDeleteWhat happens if you place a DEFER attribute on the inline SCRIPT block?
Everything I've read indicates that if you care about the execution order of the code you probably don't want to do that (if you're defining variables in the inline code, deferring it could cause the code that needs the variables defined to execute before they are defined).
ReplyDeleteIt also looks like defer isn't (or wasn't) really supported outside of IE so it wouldn't get you the same bang as just moving the code block.
Defer is supported by Firefox 3.5+ (with changes in 3.6 to ban the attribute on inline scripts, prompted by changes in the HTML5 spec). Support in Webkit is a work in progress.
ReplyDeleteFor the most part the newer browsers do not have the same blocking problem with javascript that the earlier browsers do so you won't see the problem above on IE8, Firefox 3.6+ or Chrome (not sure which version added non-blocking).
ReplyDeleteThat said, even if the new browsers had the problem, defer wouldn't help because it's the inline script you'd need to defer.
I found a way to have inline JS + <script> includes at the bottom :
ReplyDelete- put JS at the bottom and mute the errors
- execute the page
- unmute errors
- include the <script>
- eval() all inline scripts
full post here, in french (but code examples and graphics are readable) :
http://jpv.typepad.com/blog/2010/05/performances-web-put-scripts-at-the-bottom-oui-mais-comment-.html
@jpvincent: what does mute errors mean?
ReplyDeleteWhat happens if you place a DEFER attribute on the inline SCRIPT block?
ReplyDeletesee here
What happens if you place a DEFER attribute on the inline SCRIPT block?
mute means catching the onerror JS and setting a dummy function in order for the user not to see the errors throwned by the JS engine
ReplyDeleteMy site shows the Inline script block #2 Dreamstopixels I checked everywhere inside header.php and index.php for inline scripts but i couldn't find what was the error, if anyone knows how to fix it please send an email to me Thanks
ReplyDeleteFYI, this "sandwich problem" seems to be no longer relevant with modern browsers for the past few years. I bet that preloaders are smarter now and will more agressively fetch external scripts after inline script blocks (even if the inline script could theoretically render that download useless).
ReplyDeleteI could replicate the issue in Firefox 10, but the problem didn't exist in the oldest versions of IE and Chrome that I could test (IE 9 and Chrome 14).