Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong><em>Edit (2012 October):</em></strong> ASP.NET 4.5 now includes <a href="http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification" rel="noreferrer">Bundling and minification</a>. The current version doesn't support dynamic javascript generation very well, but it's otherwise pretty usable and for instance does watch the filesystem to live changes as described below; before rolling your own compression, try that!</p> <p><strong><em>Old answer:</em></strong></p> <p>Rather than implement this at build time, I suggest you do so at runtime. This has a number of advantages:</p> <ul> <li>You can include debugging parameters that turn off the combining and minification to permit easier identification of errors. This also allows you to run with less difference between development and production environment.</li> <li>You gain some flexibility. I've twice been able to fix errors via a script-only fix that can go live directly. For simple but critical errors that's a nice option.</li> <li>It's quite a bit simpler to implement - you already have the expertise in implementing http responses, which applies nicely here.</li> <li>You can track the last-modified date of the scripts involved, and not only use that to set the appropriate ETags and whatnot (which IIS can do too), but rather set a far-future expiry date. Then, rather than linking the actual scipt (whether minified or not), you can link the script with some short token in the querystring - that way clients don't need to check whether the js has updated. When it has, the pages will link to a "new" script file that needs to be separately requested anyhow. (This is possible to do in build scripts, but trickier).</li> <li>A complex build process often has hidden costs. Not only does it take longer to run, but what happens when you want to update your build automation tool? When you switch IIS or windows versions? When you migrate to VS 2010? How easy is it to bring new developers up to speed?</li> </ul> <p>This is the rough outline of the process I follow:</p> <ol> <li>I specify two directories as containing only compressible css and js. At appdomain instantiation or shortly thereafter via a static constructor, a class finds the contents of those directories and creates a <a href="http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx" rel="noreferrer"><code>FileSystemWatcher</code></a> to watch for changes.</li> <li>All files are read in order of filename (using prefixes such as <code>00_jquery.js</code> <code>10_init.js</code> etc. helps control order here). The list of filenames is stored for debug purposes.</li> <li>All files are combined via string concatenation, then minified by YUI, then compressed via <code>GZipStream</code>. A version specific token is computed either by newest last-modified date or by the hash of the result.</li> <li>The result of the compression (byte array, filenames, and version-specific token) is stored in a static class variable (protected by a <code>lock</code>). If the file system watcher detects an update, step 2 starts again and runs in the background until the compression completes - hence the locking.</li> <li>Any page wishing to include the combined javascript (and/or css) calls the shared static variable. If we're in debug mode, that generates a script (or link) tag for each filename as stored in step two, otherwise, this generates a single script (or link) tag to a Uri that's handled by a custom <code>IHttpHandler</code>. All Uri's include the version-specific token in the querystring - this is ignored both by the IIS static file handler and the custom http handler for the combined minified version, but makes caching easy.</li> <li>In a custom IHttpHandler, when a request for the combined javascript (or css) is received, the Content-Encoding: gzip header is set, and a far-future Expiry date. Then the precompressed byte array is written directly to the http stream via <code>context.Response.OutputStream</code>.</li> </ol> <p>Using that approach, you won't need to fiddle with web.config options whenever you add or remove a script file; you can update scripts while the app is running and clients will request these on the very next page view - but you still will get optimal cache behavior since browsers won't even send an If-Not-Modified request due to the expiry header. Usually, compressing scripts should take a second or so and the compressed result should be so small that the memory overhead of the static variable is negligible (at most a few 100 KB for a truly large amount of scripting / css).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload