Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / CSS

A Smarter Way to Include JavaScripts and CSS to Reduce Page Load Times

4.78/5 (31 votes)
17 Apr 2011MIT5 min read 100.3K   819  
Reduce the number of HTTP requests required to render the page, resulting in faster page loads by combining and compressing multiple JavaScripts into one JavaScript file and multiple CSS files into one style sheet file.

Introduction

How fast a web page can be displayed is still an important issue. Nowadays, it's not as much how quick the page is rendered at the server that should be the key focus, rather the user experienced load time at the client. Web pages tend to get more and more scripts to handle things like nicer interactions and smoother communication (like Ajax). This tends to prolong the load time since the scripts are loaded synchronously, one round trip to the server for each file to include. The same goes for stylesheets.

A way to speed things up is to manually place all the JavaScript in one single file and then minify it. That's good, but it introduces some new problems, like that debugging would become much harder.

Enter the Solution

Wouldn't it be great if it was possible to keep the scripts and stylesheets as separate files, in human readable format, but at the same time send a minified all-in-one file to the web browser? Maybe even gzip-compressed to optimize the transport even further? Well, that's what we'll do here in this article! 

Let's start by setting some design goals for our new component that will deliver this magic:

This code should ...

  • .. be built as a WebControl.
  • .. usage shouldn't be harder than current <script> and <link>-tags.
  • .. handle both JavaScript and stylesheets.
  • .. produce a single, minified versions of the scripts/stylesheets.
  • .. deliver this file gzip:ed if requesting web browser is compatible.
  • .. have an easy way to disable it to ease script debugging.
  • .. only recompact the files if any of them has been changed (use smart caching at the server).
  • .. cache the files at the client, but in a manner that will reload any changed file.
  • .. NOT reinvent the wheel. Reuse proven code to minify both scripts and styles.

As there are a few really good minifiers/compressors out there, I decided to use one of them instead of writing my own. The choice fell on Yahoo! UI Library: YUI Compressor for .NET (under Ms-PL licence) since it's well proven to work and does a really good job. If you however feel like using some other code for compressing the scripts/CSS, you will be able to easily change the implementation in the classes CssMinifier and JavascriptMinifier.

Using the Code

I won't go into too much detail of the actual implementation, since I've tried to comment as much of the code itself as possible. But I will give you a little starting point by describing the different classes in this project.

FileDescription
Common.csCollects useable functions that are called from other parts of the project.
Config.csIncludes all properties read from the web.config file.
CssMinifier.csCode to handle the compression and minification of the stylesheets.
GetPackedFile.csPage codebehind which will be used to get the right file on request from client.
IncludeCss.csWebControl to use on your pages in order to collect the stylesheets that should be packed together.
IncludeScript.csWebControl to use on your pages in order to collect the JavaScripts that should be packed together.
JavascriptMinifier.csCode to handle the compression and minification of the JavaScript files

Using SmartInclude in your Project

I assume you have a working assembly, either from the demo project or one which you've built yourself.

I will also assume (most possible wrongly, but it makes the instructions easier to write) that you have one single aspx file for your page. You are more likely to use master pages and user controls to your pages (if not, you might want to consider). The changes to the page in the instructions below should also be made to your master pages (.Master) and user controls (.ascx). Regardless of where your includes are made, in the page itself, the page's master or any user controls within the page, the JavaScript and style sheets will be included into just one file (per type, meaning one CSS and one JavaScript).

Let's start by adding SmartInclude to your project in the following steps:

  1. Open your project.
  2. Add a reference to the SmartInclude assembly (or project if you intend to do some debugging) for your web project.
  3. Open your web.config file and add the following lines in your appSettings-section:
    ASP.NET
    <add key="SmartIncludeDebugMode" value="false" />
    <add key="SmartIncludeXhtmlMode" value="false" />
    <add key="SmartIncludePath" value="/includes/" />

    Change the values to match your project. The values are:

    KeyDescription
    SmartIncludeDebugModeSet the value to true in order to enable debugging. In debug mode, the included files are loaded in the original, uncompressed/non-minified version as they appear on the server.
    Should be set to false unless you actually are debugging the code as this will override any speed ups!
    SmartIncludeXhtmlModeSet this to true if you are using XHTML so that SmartInclude will render the HTML tags correctly.
    SmartIncludePathSet this to the absolute path where you want to store the compressed files and load them from.
  4. Copy Get.aspx from the SmartInclude project into the same path you wrote in SmartIncludePath (in the previous step).

Do the following steps for all pages you want to speed up:

  1. Open the aspx file for the page you wish to speed up by using the SmartInclude web control.
  2. Add a line in the top (as the second line) to register the SmartInclude web control on your page:
    ASP.NET
    <%@ Register TagPrefix="smart" Namespace="Kaliko.SmartInclude" 
    	Assembly="Kaliko.SmartInclude" %>
  3. For all JavaScript includes, change:
    JavaScript
    <script type="text/javascript" 
    	src="http://www.codeproject.com/myScript.js"></script>

    into:

    JavaScript
    <smart:IncludeScript Url="/myScript.js" runat="server" />
  4. For all CSS includes, change:
    ASP.NET
    <link rel="stylesheet" 
    	href="http://www.codeproject.com/style.css" type="text/css">

    into:

    ASP.NET
    <smart:IncludeCss Url="/style.css" runat="server" />

That's it! You've just speeded up the user perceived page load times in your web project.

Points of Interest

There are plenty of useful tools around to help you to speed up the page loading. Two of these are YSlow from Yahoo and Page Speed from Google, both available as plugins for Firefox (with the Firebug plugin installed). I suggest you try these plugins for further suggestions of optimization points (now when your script and stylesheet includes should get a grade A ;)).

There's also one known limitation in the code. It doesn't handle different media targets for stylesheets. For instance, if you have a different stylesheet for printing, it should still be included by the <link> tag.

History

  • 1.2.0 - Latest sources with a few fixes applied
  • 1.0 - Public release
  • 0.9 - Proof of concept

License

This article, along with any associated source code and files, is licensed under The MIT License