Overview

Architecture

The script compression library exposes and httphandler for handling single script requests, a route handler for handling composite script requests, and mvc html helper extensions to generate composite resource requests.

Caching

The scripts will be cache on client for a year or to the configured number of days if configured. The handlers write a cache header in the response.
If CompositeResourceSettings.Version is configured the version will be appended to the script source url. This will force the user to download new scripts when a new build/version is deployed.
The version property must be set by the caller at runtime. If it is not set no version will be appended to the src url. The version property is static so it only needs to be set once.
ex.


//old version
<script src="/content/some.js?v=22334455" />
 
//new version
<script src="/content/some.js?v=32334466" />

Http Route Handlers

Single Script Request Handler

The ScriptResourceCompressionHandler http handler will intercept all js and css requests if configured in the web.config and compress and cache the script file. This handler uses the same minification classes that the composite resource handler uses. The handler will load the compressed file into web cache for fast access on the next request.

Composite Script Resource Route Handler

The CompositeResourceRouteHandler handles all requests to the specified composite resource controller/action route. The route is currently hard coded in the MVC html extension when generating the script resource. The handler will pull the compressed resource from the web cache based on the key and script type passed on the route path parameters. The route handler must be added as a route in the route table, this can be done in the global.asax file.

MVC Html Extensions

Composite Script MVC Html Extension

The CompositeScriptResource mvc extension will create composite script resource from a list of scripts passed to it or from a predefined list of scripts in a configuration file. The helper will combine all scripts from disk into one script, compress the resulting script, and then add the script to the web cache with the specified key. The extension will then write a script tag in the html with the composite route path to access the script. If the key passed already exists in the cache the extension will only create the composite script route path script tag and bypass the script combining/compression logic.
The CompositeScriptResource extension will compress scripts together in the order they were passed or configured. This allows any onload events in the js files to load in the correct order and any script dependencies will be resolved.

MVC Extension Methods

The CompositeScriptResource contains to html helper methods that will generate a composite resource:
  • CompositeScriptResource.CompositeScriptResource_CompositeScript(HtmlHelper helper, List<string> scripts, string Name, ResourceType type) - Generates composite script from list of scripts.
  • CompositeScriptResource.CompositeScriptResource_DefinedCompositeScriptResource(HtmlHelper helper, string Name) - Gernerates composite script from configuration file.
  • CompositeScriptResource.CompositeScriptResource_RenderScriptTag(HtmlHelper helper, string virtualPath) - renders a single script file
The CompositeScriptResource.CompositeScriptResource_CompositeScript() method is useful if you have a scripts that are specific to a view and does not make since to add to the configuration file but should be compressed.
The CompositeScriptResource.CompositeScriptResource_DefinedCompositeScriptResource() method provides compression for script frameworks, this allows for the definition of the files which compose the framework to be definied in one place, the configuration file, and used throughout the application views.

Using Composite Resource Script Library

Using in Views

The view needs to import the composite resource mvc extension resource.
ASP.Net:

<%@ Page Title="Visible Intelligence - Analysis" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
 
<%@ Import Namespace="DB.MVC.Extensions.Compression" %>
<%@ Import Namespace="DB.MVC.Extensions.Compression.Resource" %>
 
//rest of view code


Razor:

@inherits System.Web.Mvc.WebViewPage
 
@using DB.MVC.Extensions.Compression;
@using DB.MVC.Extensions.Compression.Resource;
 
\\rest of code

Single Script File

To render a single script file, with compression and build cache expiration use the RenderScriptTag Extension method.

//Asp.Net
 
<%=Html.CompositeScriptResource_RenderScriptTag("~/Content/CSS/ie9.css")%>
 
//Razor
@Html.Raw(Html.CompositeScriptResource_RenderScriptTag("("~/Content/CSS/ie9.css"))

Using CompositeScript

Use CompositeScriptResource.CompositeScript() method when compressing scripts inline in the view. Pass in all virtual script paths to be compressed, the composite resource key to identify the resource, and the type.

JS Script

Creating a Composite resource of javascript. Use ResourceType.JS enum value as the type.

//view code
 
//ASP.Net
 
  //create composite script
  //using the mvc html helper extension
    <%= Html.CompositeScriptResource_CompositeScript( 
          new List<string>(){
            "~/Scripts/HighCharts/js/highcharts.js",
            "~/Scripts/HighCharts/js/modules/exporting.js",
            "~/Scripts/Utility/jQueryAjaxManager.js",
            "~/Scripts/Controllers/AjaxQueueManager.js",
            "~/Scripts/Utility/jquery.address-1.0.js",
            "~/Scripts/Utility/HttpUtility.js",
            "~/Scripts/Utility/ErrorHelper.js",
            "~/Scripts/Utility/Utilities.js",         
            "~/Scripts/Objects/Query.js",
            "~/Scripts/Objects/QueryFilter.js"            
            },
      "AnalysisFramework",
       ResourceType.JS) %>
 
 
//Razor
     @Html.Raw(Html..CompositeScriptResource_CompositeScript( 
          new List<string>(){
            "~/Scripts/HighCharts/js/highcharts.js",
            "~/Scripts/HighCharts/js/modules/exporting.js",
            "~/Scripts/Utility/jQueryAjaxManager.js",
            "~/Scripts/Controllers/AjaxQueueManager.js",
            "~/Scripts/Utility/jquery.address-1.0.js",
            "~/Scripts/Utility/HttpUtility.js",
            "~/Scripts/Utility/ErrorHelper.js",
            "~/Scripts/Utility/Utilities.js",         
            "~/Scripts/Objects/Query.js",
            "~/Scripts/Objects/QueryFilter.js"            
            },
      "AnalysisFramework",
       ResourceType.JS))
 
//rest of view code


The resulting output in the view html will be:

<script src="CompositeScriptResource/getresource/AnalysisFramework/JS" type="text/javascript" />

CSS Script

Creating a Composite resource of CSS. Use ResourceType.CSS enum value as the type.

//view code
 
//ASP.Net
  //create composite script
  //using the mvc html helper extension
    <%= Html.CompositeScriptResource_CompositeScript( 
          new List<string>(){
            "~/Scripts/CSS/highcharts.css",
            "~/Scripts/CSS/exporting.css"           
            },
      "AnalysisFrameworkCSS",
       ResourceType.CSS) %>
 
 
  //Razor
     @Html.Raw(Html..CompositeScriptResource_CompositeScript( 
         new List<string>(){
            "~/Scripts/CSS/highcharts.css",
            "~/Scripts/CSS/exporting.css"           
            },
      "AnalysisFrameworkCSS",
       ResourceType.CSS)) 
 
//rest of view code


The resulting output in the view html will be:

<link href="CompositeScriptResource/getresource/AnalysisFrameworkCSS/CSS" rel="stylesheet" type="text/css" />

Using DefinedCompositeScriptResource

This extension method will create a composite script resource from a predefined list of files a script resource configuration file.

Using in Views

Import the compression library namespaces in the view. Then use the DefinedCompositeScriptResource() extension method.


//view code
 
//Asp.Net
  // generate Javascript composite script resource include for Master framework, "MasterFramework" is the key in the configuration file
  <%= Html.CompositeScriptResource_DefinedCompositeScriptResource("MasterFramework")%>
 
//Razor
 @Html.Raw(Html.CompositeScriptResource_DefinedCompositeScriptResource("MasterFramework"))
 
//rest of view code


The resulting output in the view html will be:

//javascript resource
<script src="CompositeScriptResource/getresource/MasterFramework/JS" type="text/javascript" />
 
//css resource
<link href="CompositeScriptResource/getresource/MasterFramework/CSS" rel="stylesheet" type="text/css" />

Composite Script Resource Configuration

Create an xml/config file in the web project which follows the schema outlined below and configure all composite script resource definitions.
Configuration Elements:

<?xml version="1.0" encoding="utf-8" ?>
<CompositeScriptResources>
  <CompositeScriptResource Name="{key}" type="{CSS or JS} ResourceType Enum">
    <script path="{filepath}" />
  </CompositeScriptResource>
</CompositeScriptResources>


Example:

<?xml version="1.0" encoding="utf-8" ?>
 
<CompositeScriptResources>
 
  <!-- CSS Resource -->
  <CompositeScriptResource Name="MasterFrameworkCSS" type="CSS">
    <script path="~/Content/CSS/yahooReset.css" />
    <script path="~/Content/CSS/core.css"/>
    <script path="~/Content/CSS/views/sitemaster.css" />
    <script path="~/Content/CSS/theme/theme.css" />
    <script path="~/Scripts/jquery/themes/jquery-ui-1.8.2.custom.css" />
  </CompositeScriptResource>
 
  <!-- Javascript Resource -->
  <CompositeScriptResource Name="MasterFramework" type="JS">
    <script path="~/Scripts/jquery-1.4.2.js"/>
    <script path="~/Scripts/jquery/ui/jquery-ui-1.8.2.custom.min.js" />
    <script path="~/Scripts/Controls/DropDownPlugin.js" />
    <script path="~/Scripts/Objects/DateExtensions.js" />
    <script path="~/Scripts/core.js" />
  </CompositeScriptResource>
 
</CompositeScriptResources>

Web Site Configuration

Include the following areas in the web configuration file to use the Composite Script Resource Compression library.

<configuration>
  <configSections>
    <section name="CompositeScriptResourceSection" 
             type="DB.MVC.Extensions.Compression.Configuration.CompositeResourceSection, DB.MVC.Extensions.Compression" 
             allowLocation="true" 
             allowDefinition="Everywhere" />
  </configSections>
 
  <!-- Composite Script Resource Configuration Section
  Enabled attribute: turns off compression for debugging
  DefinedCompositeResourcePath: Path to composite script resource configuration file
  -->
 
  <CompositeScriptResourceSection
     Enabled="true"
     DefinedCompositeResourcePath="~/CompositeScriptResource.config"
     ClientCacheDays="1" //optional, if left empty or 0 will default to 1 year cache
   />
 
 
<system.webServer>
  <handlers>
 
  <!-- Compress single Javascript file requests -->
   <add name="JsCompress" path="*.js" verb="*" type="DB.MVC.Extensions.Compression.ScriptResourceCompressionHandler" resourceType="File" />
 
   <!-- Compress single CSS file requests -->
   <add name="CssCompress" path="*.css" verb="*" type="DB.MVC.Extensions.Compression.ScriptResourceCompressionHandler" resourceType="File" />
 
  </handlers>
</system.webServer>

In the global.asax file add the following route to the route table:

protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
 
            //Set the version for the ?v= query string paramter for requests
            Version v = Assembly.GetExecutingAssembly().GetName(false).Version;
            string version = string.Format("{0}{1}{2}{3}", v.Major, v.Minor, v.Build, v.Revision);
            CompositeResourceSettings.Version = version;
        }
 
 
        public static void RegisterRoutes(RouteCollection routes)
        {
            //additional route registration code here, removed
            //script compression route handler
            Route compositeScriptRoute = new Route("CompositeScriptResource/getresource/{name}/{type}", new CompositeResourceRouteHandler());
            RouteTable.Routes.Add(compositeScriptRoute);
        }

Debugging Scripts

In most cases script compression will need to be disabled and composite script create will need to be disabled when debugging. The framework allows for an easy way to accomplish this.
In the web.config file change the CompositeScriptResourceSection Enabled attribute to false to turn off compression and composite script creation.

//web.config
 
 <CompositeScriptResourceSection
     Enabled="false"
     DefinedCompositeResourcePath="~/CompositeScriptResource.config"
   />

Enabling Disabling Via Cookie

Script compression can be enabled or disabled by adding a cookie to the domain.
Add the cookie “VTUncompressScripts” to uncompress scripts, remove the cookie to compress scripts
Add the following JS shortcuts to the browser to make this easier.

//UnCompress - adds cookie:

 javascript:(function(){document.cookie="UncompressScripts=true;path=/";})()

//Compress - removes cookie:

javascript:(function(){var date = new Date();date.setTime(date.getTime() - 1);var temp = date.toUTCString();document.cookie="UncompressScripts=false;path=/;expires="+temp;})()


Now all files will be requested individually without compression. The framework will write script tags for each script in the html, or link tags for CSS.

<!-- Composite resource now writes for JS -->
<script scr="file.js" type="text/javascript" />
<script scr="file2.js" type="text/javascript" />
<script scr="file3.js" type="text/javascript" />
<script scr="file4.js" type="text/javascript" />

<!-- Composite resource now writes for CSS -->
<link href="stylesheet.css" rel="stylesheet" type="text/css" />
<link href="stylesheet1.css" rel="stylesheet" type="text/css" />
<link href="stylesheet2.css" rel="stylesheet" type="text/css" />

Last edited Apr 9, 2012 at 2:55 AM by DougBranca, version 2

Comments

No comments yet.