A Better Way to Include JavaScript and CSS in your Web-Apps (Break Proxy and Browser Caching too!)

| No TrackBacks
Most web-apps include a number of JavaScript and CSS files, that in most cases, need to be included/sourced on every page of the application.  Doing so can bring up a few, while trivial, often annoying problems:

  • Dependencies between scripts.  For example, if you attempt to use a jQuery plugin before the base jQuery library has loaded into the browser you'll obviously see an error.  Working out these dependencies before hand can save you a few headaches.

  • Web-browsers and web-proxies cache your JavaScript and CSS files too often.  I can't count the number of times on two hands when I made a small change to a JavaScript file, saved the change, refreshed my browser, and .... nothing.  The web-browser didn't load the changed file; instead, it loaded the JavaScript from cache.  Using a mechanism to always force the web-browser or web-proxy to reload your JavaScript and CSS can save you time.
Meet Gagawa, an open source object-oriented HTML generation engine written in Java and PHP.  You probably wouldn't build an entire site with Gagawa, but it's absolutely perfect for small HTML tasks, like solving this irritating dependency and caching problem.

Using Gagawa PHP, problem solved:

<?php

require_once("gagawa.php");

$js = array(
// The base jQuery library, needed by all other
// jQuery plugins and your jQuery code.
"/js/jquery-1.3.2.min.js",

// jQuery plugins; jQuery base needs to be loaded
// before you source these.
"/js/jquery.ui.min.js",
"/js/jquery.hotkeys.min.js",

// Some other, unrelated JavaScript library like
// underscore JS.
"/js/underscore.min.js",

// Your JavaScript, with dependencies on jQuery, the
// jQuery plugins and Underscore JS, should be loaded
// last.
"/js/yourjs.min.js"
);

$css = array(
"/css/othercss.min.css",
"/css/yourcss.css"
);

// Build <script ...></script> for each JavaScript
// we need, in order. Use time() to break browser
// caching.
foreach ($js as $url) {
$script = new Script("text/javascript");
echo $script->setSrc($url."?".time())->write();
}

// Build <link ...></link> for each CSS file we need,
// in order. Use time() to break browser caching.
foreach ($css as $url) {
$link = new Link();
$link->setHref($url."?".time())->setRel("stylesheet")->setType("text/css");
echo $link->write();
}

?>

This code snippet generates some solid output that fits nicely into the <head> of your HTML:

<script type="text/javascript" src="/js/jquery-1.3.2.min.js?1261531930"></script>
<script type="text/javascript" src="/js/jquery.ui.min.js?1261531930"></script>
<script type="text/javascript" src="/js/jquery.hotkeys.min.js?1261531930"></script>
<script type="text/javascript" src="/js/underscore.min.js?1261531930"></script>
<script type="text/javascript" src="/js/yourjs.js?1261531930"></script>

<link href="/css/yourcss.css?1261531930" rel="stylesheet" type="text/css"></link>

Note that each JavaScript and CSS file is loaded and added to your HTML, in order as desired, eliminating any stray dependency issues.  Also, note that I'm appending "?" and the current Epoch timestamp to the end of the JavaScript source URL, and CSS Href.  PHP's time() function works nicely here because I'll get a different timestamp on each page load.  And as far as the browser (or a web-proxy) is concerned, "/js/yourjs.min.js?1261534594" is different than "/js/yourjs.min.js?1234567890" and will be treated as such.  With this mechanism, every time you refresh the page, the browser will be forced to reload and reevaluate your scripts.  Say goodbye to browsers caching and not recognizing your changes!

You can download the latest version of Gagawa at http://code.google.com/p/gagawa/downloads/list.  Also, if you're interested, other Gagawa examples can be found on the Gagawa homepage.

If you're looking for a real, live, example of this technique in action check out Onyx.

Merry Christmas.

Did You Find this Helpful?

Did you find this post helpful, or at least, interesting?

  

Send Mark a Direct Message

If you'd like to send me a direct message, please do so below. However, I do not publicly post comments or messages submitted directly to me. So, if you're going to try to SPAM me, or my blog, you're pretty much wasting your time.

400 characters remaining

Error

About Mark

A Silicon Valley native, Mark Kolich is a full-time Software Engineer, a casual entrepreneur, and a consultant for hire. A web technologies expert, his current focus is on building powerful and robust cloud-driven web-applications using Java, PHP, Perl, AJAX, DHTML, CSS, and JavaScript. His favorite programming languages are PHP, Java and JavaScript. He uses Linux, enjoys biking to work, loves building great software, and always writes elegant, readable, and maintainable code.

No TrackBacks

No trackbacks attached to this entry.

Twitter (@markkolich)

Translate

About this Entry

This page contains a single entry by Mark Kolich published on December 22, 2009 6:30 PM.

Writing Your Own Animation Loop with javax.swing.Timer was the previous entry in this blog.

Experimenting with More Domains, and Fun with Http 302 Found is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.