Wednesday, July 30th, 2008

Inline Script Wrapper and Dependencies

Category: jQuery, Performance

<>p>Stuart Colville has found an issue where he needed to output some JavaScript in the middle of a page, before a library that depended on it was available:

The 6th Rule in Yahoo’s Performance Rules recommends placing script before the closing body tag to prevent blocking holding up the rendering of the page’s content. This works well but there are times where script needs to be output higher up in the page than it’s dependencies.

In this example I’m using jQuery but feel free to substitute jQuery for the your favorite framework.

The requirement is that there’s a need to run some code that would ideally use jQuery somewhere in the middle of the page. I could avoid the dependency and re-write everything without jQuery and for simple scripts this can be a good way to go. But, if I want to use some of the more complex jQuery features, then I really don’t want to have to re-invent the wheel or resort to including jQuery in the head of the document.

This lead him to the following example

  1. <script type="text/javascript">
  2.         var muffin = muffin || {};
  3.         muffin.inline = muffin.inline || [];
  4.         muffin.inline.add = function(f){
  5.            muffin.inline[muffin.inline.length] = f;
  6.         };
  7.     </script>
  8.  
  9.     <script type="text/javascript">  
  10.         muffin.inline.add(function(){
  11.             $('#green')[0].style.backgroundColor = 'green';
  12.         });
  13.         muffin.inline.add(function(){
  14.              $('#red')[0].style.backgroundColor = 'red';
  15.         });
  16.     </script>
  17.  
  18.     <div id="red"><p>This should be Red</p></div>
  19.     <div id="green"><p>This should be Green</p></div>
  20.  
  21.     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
  22.     <script type="text/javascript">
  23.         $(function(){
  24.             if (muffin && muffin.inline){
  25.                for (var i=0, j=muffin.inline.length; i<j ; i++){
  26.                    muffin.inline[i]();
  27.                }
  28.            }
  29.        });
  30.    </script>

This seems a little niche. You my run into this as you have server side components outputting things, but ideally you can fix that in your architecture and ship the JavaScript in the correct location.

Related Content:

Posted by Dion Almaer at 5:42 am
4 Comments

++---
2.5 rating from 8 votes

4 Comments »

Comments feed TrackBack URI

Okay, this is kinda of a paradox. He would put the JS on the bottom of the page because that would give him a performance boost (at least that is what YSlow is claiming) but then he creates an extra loop which isn’t actually necessary because he could put the code that he does inline now right after loading jQuery. His solution would be more system intensive than loading the JS in the head-section.

And what’s wrong with:
$(“#green”).css(‘background-color’:'green’);?

Comment by AriesBelgium — July 30, 2008

Sorry, typo:
$(“#green”).css(‘background-color’,'green’);

Comment by AriesBelgium — July 30, 2008

I ran into this having a SCRIPT element within a WordPress post. I needed $, but it wasn’t defined until the end of the page. Now a trivial plugin loads directly after jQuery to call any queued functions. Usage is easy:

// setup func to be called later
var _waitFor$ = function () {
$(doSomething);
};

Comment by Steve Clay — August 1, 2008

I don’t agree with this at all.

I’m not the world’s biggest fan of doing a load of style in your JS, as that defeats the object of CSS in my opinion.

If you really must do stuff like that in JS, then here’s a simple solution…

On the first line directly after the body tag has been opened, add this:
document.body.className += ‘ hasJS ‘;

Now, in your JS, you could do this:
body.hasJS #red {background-color: #F00;}
body.hasJS #green {background-color: #0F0;}

Isn’t that better? This way you can still have your JS at the bottom of the page, and your elements will be styled correctly.

Comment by DanAtkinson — August 11, 2008

Leave a comment

You must be logged in to post a comment.