0

It's oft recommended optimization to consolidate your javascript into fewer parts and reduce the number http requests. On a smaller site you could easily arrive at structure like:

/js/jQuery-xx.js
/js/plugins.js
/js/app.js

Even in a modest site (with just some jQuery polish) that app.js can get pretty heavy. For organization it's easy to break apart the implementations into logcal bits:

..
/js/app-global.js
/js/app-contact.js
/js/app-products.js
/js/app-splash.js

Now as separate files it's trivial to require them for a specific context, though their individual sizes are quite small, around 1–3 kb a piece, so it occurs to me it'd be pretty smart to recombine them back into a single file simply served as app.js.

But it occurs to me that in app.js file with about 20 or so jQuery selectors and misc javascript that goes unused on most pages. Seems like wasted CPU cycles to have these jQuery selectors firing when they target elements that don't exist in most contexts.

Which is the more pressing optimization: • reducing http requests? • reducing unused jQuery selectors?

I'm using Chrome's Audit tool to profile and it recommends fewer network request for javascript files. Any guidelines for measuring bloat in jQuery.ready(…);?

Update

Weighing the evidence presented the simplest thing to do is to serve the implementation code as a single file and then activate different modules using a routing system. In my case I just hooked into the simple php router that I've already built:

root.php

<script type="text/javascript">
var myApp = {
    modules: {}
    bootstrap: function()
    {
    <?php
    if ( $pageId == 'contact' )
      echo 'myApp.modules.contact();';

    if ( $pageId == 'index' )
      echo 'myApp.modules.splash();';

    if ( preg_match( '~^help/~iu', $pageid ) )
      echo 'myApp.modules.faq();';
   ?>
   }      
}
</script>
<script type="text/javascript" src="/js/jquery1.9.1.js"></script>
<script type="text/javascript" src="/js/jquery-plugins.js"></script>
<script type="text/javascript" src="/js/myApp.js"></script>

myApp.js

$(document).ready(function()
{
   myApp.bootstrap();
   //… global jQuery stuff …
});

// Define modules

myApp.modules.splash = function() {
  $('#splash').click(
     //…etc…
  );
}

myApp.modules.faq = function() {
  $('.faq').show( 
     //…etc…
  );
}

myApp.modules.contact = function() {
  $('.contact').bind(
     //…etc…
  );
}
Mark Fox
  • 8,694
  • 9
  • 53
  • 75
  • It partially depends on which bugs you more: initial loading delay (especially considering the scripts will get cached) or bad performance once the page has loaded. – Asad Saeeduddin Jun 12 '13 at 22:59

2 Answers2

3

Serving your static content in as few files as possible is always the recommendation. If you're worried about executing on content that doesn't exist then you should organize your code in such a way that it doesn't all automatically fire on page load, but fires when you tell it to. That way you only execute the code you want to on any given page. The easiest way would be to wrap each pages content in it's own function:

window.aboutPage = function() {
    $('').css(); //some stuff
}

then at the bottom of the about page, after your load all your external scripts fire off the appropriate function

<script>$(window.aboutPage) //fire aobutPage stuff on ready</script>

There are frameworks that can accomplish this modularization of code also

Matt Berkowitz
  • 975
  • 6
  • 13
1

If you're using modules (I'm guessing RequireJS?) you can avoid putting a bunch of functions on the global/window object by implementing a simple "router". Have your main app module define a hash of "routes" something like:

var routes = {
    '/contact': contact,
    '/products': products,
    '/splash': splash
};

Where each of contact, products, and splash, is the function you want to call "on DOM ready". Then elsewhere in your same app module pass the appropriate function as jQuery's ready handler something like:

$(routes[window.location.pathname])

Note that:

  1. You might need to do something fancy to make sure you're only using the part of the URL/path that you really want.
  2. You could drop the jQuery dependency (if you want) and use RequireJS's domReady. They apparently work about the same.
Community
  • 1
  • 1
mysterycommand
  • 926
  • 8
  • 8
  • I'm actually doing the routing in PHP, and this project just uses jQuery, since it's a more 'traditional' page based project. But, yes, in the end I guess what I need is a module activation system. – Mark Fox Jun 13 '13 at 17:36