Combine CSS with JS and make it into a single download!

Now, if you have by any chance worked on page load optimizations, you would know how costly each resource download is.  The more the number of external resources that you refer to, the more the time it takes for the page load to complete. 

Typically, web pages refer to many external CSS and JS files and hence incur many resource downloads.  The advice from the PLT (page load time) gurus is to combine all the CSS files into one and all the JS files into one so as to reduce the number of resource downloads to just two.  This, without any doubt, would help boost your PLT.

If you feel that two downloads still isn't the best, I concur.  In this post, we'll look at a technique to combine CSS with JS and get the resource download count to one!  I discovered this technique while desperately trying to improve the page load time for the pages in Microsoft Office Live.  Read on...

The technique relies on how CSS and JS parser behaves in IE and Firefox. 

  • When the CSS parser encounters a HTML comment token (<!--) in CSS content, the token gets ignored.
  • When the JS parser encounters a HTML comment token (<!--) in JS content, the token is treated similar to the line comment (//) and hence the rest of the line following the HTML comment token gets ignored

Look at the below JS+CSS code snippet...

<!-- /*
function t(){}
<!-- */
<!-- body { background-color: Aqua; }

When the CSS parser parses the above content, the HTML comment tokens would be dropped and the snippet would become equivalent to the one below...

/*
function t(){}
*/
body { background-color: Aqua; }

As you can see above, the CSS parser will get to see only the CSS code and the script code would appear to be within the comments (/* ... */).

 

In similar lines, when the JS parser parses the content, the HTML comment tokens would be treated as line comments (//) and hence the code snippet would become equivalent to the one below...

// /*
function t(){}
// */
// body { background-color: Aqua; }

As you can see above, the JS parser will get to see only the script code and the rest of the contents would look like comments.

You can refer to the above content in both the SCRIPT and LINK tags in your HTML page.  For e.g.,

<link type="text/css" rel="stylesheet" href="test.jscss" />
<script type="text/javascript" language="javascript" src="test.jscss"></script>

Note above that both the tags refer to the same source and hence it would be downloaded once and used as appropriate (as CSS and SCRIPT).

To round it off, there is just one more thing that you need to take care of - the response content type - it needs to be set to */* in order to affirm to Firefox that the contents can be treated as anything as appropriate.

I've attached a sample project (created with VS 2005 SP1) that demonstrates this technique.  Enjoy!

 Update: (put in place due to popular misconception) In the actual implementation you will have the JS and CSS files separately on disk.  At runtime, you'll have to combine them by adding the HTML comments appropriately and serve with the correct content type and cache headers.  You should also remember the dynamically built content so that you don't need to rebuild them for each request.  Please check out the attached sample app.  This will ensure that you don't compromise on the readability, maintainability etc. while at the same time taking advantage of the reduced number of network calls.
 

Note(s):

  • If the JS contains any multi line comments it should be removed before combining with the CSS using this technique.
  • This technique has been tested positive on IE6, IE7 and Firefox 2.0.  It may work on other browsers off the shelf or may need minor tweaks.

Share this post: email it! | bookmark it! | digg it! | reddit! | kick it! | live it!

JsCssUpdated.zip

Comments

  • Anonymous
    May 01, 2007
    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • Anonymous
    May 01, 2007
    Oh, very interesting technique - thank you for your article! Btw, I suppose that it's possible have some another trick to eliminate CSS at all - instead of writing it using ordinary CSS rules, I think it's possible to code it directly in JavaScript via manipulations on styles objects (so such file will not rely on specifics of parsers implementation in different browsers). Do you think it could be practical?

  • Anonymous
    May 01, 2007
    Which versions of IE and Firefox?  What about other browsers?

  • Anonymous
    May 01, 2007
    Combining it all into JS wouldn't be practical, as different browsers have different stylesheet doms, and Opera as of 9 didn't have a stylesheet dom at all

  • Anonymous
    May 01, 2007
    In response to: Andrew Sazonov Whist I think this is a fine idea, the problem is anyone with javascript disabled would lose their styles too.

  • Anonymous
    May 02, 2007
    This prevents effective caching.  Every time my JS changes, the "CSS" file also has to be downloaded and vice versa.  Separating the files allows them to be separately cached.

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    Great stuff, thx !

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    So after reading all of these comments - which method is better?

  • Anonymous
    May 02, 2007
    @Mike - I would suggest that you consider this method only if the page load time bothers you much.  If you are already happy with your website's load time all you need to do is to remember that you can come back to this technique when the load time starts bothering you.

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    @Anastasiosyal - thanks for your comment.  Your point about readability, maintainability etc. has already been made and answered - i.e., keep the js, css files separate on disk and combine them at runtime - please check my sample app.  I agree with your point about future reliability but there are good reasons why browsers won't break their backward compat as HTML comments were allowed into JS and CSS in the first place with a reason.

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 02, 2007
    The comment has been removed

  • Anonymous
    May 03, 2007
    Copy pasted from sla.ckers.org Comment made by trev... "I don't think there is anything dangerous about this technique (users who can upload CSS can run JavaScript already, due to expression() and -moz-binding)."

  • Anonymous
    May 03, 2007
    Good discussion happening in Ajaxian on this technique... http://ajaxian.com/archives/squeeze-css-and-js-into-one-file

  • Anonymous
    May 03, 2007
    The comment has been removed

  • Anonymous
    May 04, 2007
    I think this is a good idea

  • Anonymous
    May 05, 2007
    The comment has been removed

  • Anonymous
    May 05, 2007
    @Nick - Combining js and css and keeping them as an external resource, I agree that it will need to be refreshed every time the js or the css changes, but then how frequently do you expect such changes to happen on a production site?  As for inlining them into the HTML, I think the disadvantages here are too obvious to even write further.

  • Anonymous
    May 28, 2007
    Wow, its really cool tips! Thanks a lot!

  • Anonymous
    June 10, 2007
    Thanks a lot. Really good tips.

  • Anonymous
    April 14, 2009
    link 【レポート】IE8で互換性の実現や新機能を利用するには? - MSがサイト管理者向けガイド (1) IE8準拠のための見直しポイント | パソコン | マイコミジャーナル -- 2009-04-15 (水) 19:20:52 1つのファイルにJavaScriptとCSSをまとめて記述する方法 phpspot開発日...