By default, the package minifies and combines JavaScript and
CSS files. To use the other features, or to switch off minification or
combining of JavaScript or CSS files, add a combineAndMinify
element to your web.config file, like so:
<configuration>
...
<combineAndMinify ... >
</combineAndMinify>
...
</configuration>
The combineAndMinify element
supports these attributes and child elements:
·
active
·
minifyCSS
·
minifyJavaScript
·
combineCSSFiles
·
combineJavaScriptFiles
·
preloadAllImages
·
prioritizedImages
·
cookielessDomains
·
enableCookielessDomains
·
makeImageUrlsLowercase
·
insertVersionIdInImageUrls
·
exceptionOnMissingFile
·
removeWhitespace
·
headCaching
active
Determines when the package is active. When it is not
active, it doesn't affect your site at all and none of the other attributes or
child elements listed in this section have any effect.
Value
|
Description
|
Never
|
Package is never active, irrespective of debug mode
|
Always
|
Package is always active, irrespective of debug mode
|
ReleaseModeOnly
(default)
|
Package is only active in release mode
|
DebugModeOnly
|
Package is only active in debug mode
|
Example
<configuration>
...
<combineAndMinify active=“Always” >
</combineAndMinify>
...
</configuration>
Whether your site is in debug or release mode depends on the
debug attribute of the compilation
element in your web.config file. If that attribute is set to false, your site is in release mode (as it should be when
live). When it is set true, it is in debug mode (as
it should be in development). It looks like this in web.config:
<configuration>
...
<system.web>
<compilation debug=“true”>
...
</compilation>
...
</system.web>
...
</configuration>
Note that by default, the package is only active in release
mode - so you won't see any effect while you're developing. To ensure that the
package is active in both release mode and in debug mode as well, set active to Always, as shown in the
example above.
Note that the active attribute
acts as a master switch for the whole package. It's like the ignition in a car
- if you don't turn on the ignition (or at least the battery), pressing any
other buttons on the dashboard won't do anything.
minifyCSS
Determines whether the package minifies CSS files.
Value
|
Description
|
true
(default)
|
CSS files get minified
|
false
|
CSS files do not get minified
|
Example
<configuration>
...
<combineAndMinify minifyCSS=“false” >
</combineAndMinify>
...
</configuration>
Minifying a file means removing redundant white space and
comments. This not only reduces your bandwidth usage and download times, but
also makes it harder for outsiders to reverse engineer your web site. It also
encourages developers to add comments to their CSS files (and especially their
JavaScript files), now that those comments do not travel over the wire to the
browser.
It is normally safe to minify files, so this feature is
enabled by default. However, just in case removing white space or comments
breaks your file, the option exists to switch it off.
Remember that the package doesn't minify your source files.
It reads your source files, and minifies their content before sending them to
the browser. To save CPU cycles, it caches the minified versions, using file
dependencies (explained in https://www.packtpub.com/toc/aspnet-site-performance-secrets-table-contents#chapter_5)
to ensure cached versions are removed the moment you change the underlying
files.
minifyJavaScript
Determines whether the package minifies JavaScript files.
Value
|
Description
|
true
(default)
|
JavaScript files get minified
|
false
|
JavaScript files do not get minified
|
Example
<configuration>
...
<combineAndMinify minifyJavaScript=“false” >
</combineAndMinify>
...
</configuration>
combineCSSFiles
Determines whether the package combines CSS files.
Value
|
Description
|
None
|
CSS files are never combined
|
PerGroup
(default)
|
CSS files are combined per group. See explanation below.
|
All
|
All CSS files are combined into a single CSS file.
|
Example
<configuration>
...
<combineAndMinify combineCSSFiles=“All” >
</combineAndMinify>
...
</configuration>
To see what is meant with “per group”, have a look at this
example:
<link rel=“Stylesheet” type=“text/css” href=“/css/site1.css” />
<link rel=“Stylesheet” type=“text/css” href=“/css/site2.css” />
<script type=“text/javascript” src=“js/script1.js”></script>
<link rel=“Stylesheet” type=“text/css” href=“/css/site3.css” />
<link rel=“Stylesheet” type=“text/css” href=“/css/site4.css” />
By default, the package tries to ensure that the order of
the JavaScript and CSS definitions doesn't change when JavaScript and CSS files
are combined. It does this by grouping CSS files whose tags are after each
other. In this case, there are 2 groups - site1.css and site2.css, and site3.css
and site4.css. This causes the browser to load the CSS and JavaScrip
definitions in the exact same order as when the files had not been combined:
5.
Combined file with all CSS definitions in site1.css and site2.css
6.
script1.js
7.
Combined file with all CSS definitions in site3.css and site4.css
You get this behaviour when you set combineCSSFiles
to PerGroup (which is the default). The package
supports grouping for JavaScript files as well, which is controlled by the combineJavaScriptFiles
attribute.
Combining all CSS files into one file
If you set combineCSSFiles to All, all CSS files get combined into a single file. The
link tag to load that combined CSS file gets placed where the link tag of the
first CSS file used to be. In our example, that causes this load order:
8.
Combined file with all CSS definitions in site1.css, site2.css,
site3.css and site4.css
9.
script1.js
As you see, the CSS definitions in site3.css and site4.css
now get loaded before script1.js, instead of after
script1.js. As a result, the number of CSS files that need to be loaded is
reduced from two to one (as compared with grouping), but you also change the
order in which CSS and JavaScript definitions are loaded. It depends on your
site whether that is an issue or not.
Loading CSS files from another site
If you decide to set combineCSSFiles
to All, be sure that your site doesn't load CSS files
from another web site. This is uncommon, but if yours is one of the rare sites
that does this, consider this example:
<link rel=“Stylesheet” type=“text/css” href=“/css/site1.css” />
<link rel=“Stylesheet” type=“text/css” href=“/css/site2.css” />
<link rel=“Stylesheet” type=“text/css” href=“http://anothersite.com/css/other.css” />
<link rel=“Stylesheet” type=“text/css” href=“/css/site3.css” />
<link rel=“Stylesheet” type=“text/css” href=“/css/site4.css” />
The package never combines CSS files from other sites - not
with CSS files from your site, not with CSS files from the other site. As a
result, if you change combineCSSFiles to All, the package will combine all CSS files loaded from
your site (but not those from the other site), causing the following load
order:
10. Combined
file with all CSS definitions in site1.css, site2.css, site3.css and site4.css
11. http://anothersite.com/css/other.css
The definitions in other.css now came after those in
site3.css and site4.css, meaning they may take precedence - which could break
your CSS.
combineJavaScriptFiles
Determines whether the package combines JavaScript files.
Value
|
Description
|
None
|
JavaScript files are never combined
|
PerGroup
(default)
|
JavaScript files are combined per group. See explanation
below.
|
All
|
All JavaScript files are combined into a single JavaScript
file.
|
Example
<configuration>
...
<combineAndMinify combineJavaScriptFiles=“All” >
</combineAndMinify>
...
</configuration>
As you saw in the description of combineCSSFiles, the
package groups JavaScript files in the same way as CSS files. Similarly, if
you set combineJavaScriptFiles to All,
all JavaScript files that are loaded from your site get combined into a single
JavaScript file.
However, there is one major difference with combining CSS
files: When you combine all JavaScript files into a single file (combineJavaScriptFiles is All), the
script tag for the combined file winds up at the location where the last original script tag used to be. This in contrast to a
combined CSS file, which winds up at the location of the first
original CSS tag.
This makes life easier if you load JavaScript libraries from
external sites. If you use a popular package such as jQuery, you can load it
from the free Google Content Delivery Network (CDN) and also from the free
Microsoft CDN - which saves you bandwidth and download time (details about those
CDNs are in chapter 13 of my book (https://www.packtpub.com/asp-net-site-performance-secrets/book).
Take this example:
<script type=“text/javascript” src=“/js/script1.js” ></script>
<script type=“text/javascript” src=“/js/script2.js” ></script>
<!-- load jQuery from free Google CDN -->
<script type=“text/javascript”
src=“http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js”></script>
<script type=“text/javascript” src=“/js/script3.js” ></script>
<script type=“text/javascript” src=“/js/script4.js” ></script>
script3.js and script4.js may well be dependent on
jquery.min.js. If combineJavaScriptFiles is set to PerGroup, you wind up with this load order:
1.
Combined file with all JavaScript definitions in script1.js and
script2.js
2.
jquery.min.js
3.
Combined file with all JavaScript definitions in script3.js and
script4.js
So all definitions load in the same order as before the
files were combined, as you'd expect. Now when you set combineJavaScriptFiles
to All, you wind up with this load order:
1.
jquery.min.js
2.
Combined file with all CSS definitions in script1.js, script2.js,
script3.js and script4.js
This would probably still work well, because the definitions
in script3.js and script4.js still get loaded after those in jquery.min.js. script1.js
and script2.js now get loaded after jquery.min.js, but than jquery.min.js
wouldn't have been dependent on those files anyway.
preloadAllImages
Determines whether the package inserts code that preloads
all images when the page starts loading.
Value
|
Description
|
true
|
All images are preloaded
|
false
(default)
|
No images are preloaded (except for those specified using
child element prioritizedImages, described further below)
|
Example
<configuration>
...
<combineAndMinify preloadAllImages=“true” >
</combineAndMinify>
...
</configuration>
Normally, the browser only starts loading an image after it
has encountered its image tag in the HTML or in a CSS file. If the image tag is
towards the end of a big page, or if it takes a while to load the CSS file, it
can take a while before the image starts loading.
To get the browser to start loading all images immediately
when the page itself starts loading, set the preloadAllImages
attribute to true. The package than generates
JavaScript at the start of the page head to load each image into the browser
cache, along these lines:
<script type=“text/javascript”>
var img0=new Image();img0.src='http://www.codeproject.com/images/ball3.png';
var img1=new Image();img1.src='http://www.codeproject.com/css/chemistry.png';
var img2=new Image();img2.src='http://www.codeproject.com/images/toy4.png';
...
</script>
Now when the browser encounters an image tag, the image is
already in browser cache, so the browser can show the image right away.
prioritizedImages
Allows you to prioritize certain images for preloading.
Example
<combineAndMinify ... >
<prioritizedImages>
<add url=“images/salesbutton.png”/>
<add url=“images/logo.png”/>
</prioritizedImages>
</combineAndMinify>
If you have many images on your pages, you may want to
prioritize certain images. For example, if your “order now” button is an image,
you want that image in front of your visitors as soon as possible.
You can use prioritizedImages
without setting preloadAllImages to true. Here is how these two attributes interact:
prioritizedImages
|
preloadAllImages
|
Images preloaded
|
Empty or not present
|
true
|
All the images referred to from CSS files and all the
images on the page are preloaded. They are loaded in the order in which
their tags appear in the CSS or in the HTML. Images referred to from CSS
are preloaded before images on the page itself.
|
Empty or not present
|
false
|
None
|
One or more urls
|
true
|
All urls listed in prioritizedImages
are preloaded first, than all the other images.
|
One or more urls
|
false
|
Only the urls listed in prioritizedImages
are preloaded
|
You can list any image urls in prioritizedImages,
not just urls of images that are used on the page. If you know which page
visitors are likely to go to next, you could use this to preload the images used
on that next page.
cookielessDomains
To have your JavaScript, CSS and image files loaded from one
or more cookieless domains, specify those domains using a cookielessDomains
child element.
Example
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain=“http://static1.mydomain.com”/>
<add domain=“http://static2.mydomain.com/”/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
Cookieless domains help you boost web site performance in
two ways. They let you cut down on the overhead created by cookies. And they
let you get the browser to load more JavaScript, CSS and image files in
parallel. Let's look at the cookie overhead first, and then the parallel
loading.
Cookie overhead
If your site sets a cookie on the browser, then each time
the browser sends a request to your site, that request contains the cookie. The
issue is that the cookie is not only sent when requesting an .aspx file, but
also when requesting static files, such JavaScript files, CSS files and images.
In most cases, this is a waste of bandwidth (the exception would be if you have
a handler that processes for example JavaScript files and that uses the
cookie).
However, the browser won't send the cookie to another domain
or sub domain. So if your page is at http://www.mydomain.com/page.aspx
(using subdomain www), and you put your images and
other static files on http://static1.mydomain.com
(using subdomain static1), than the browser won't
send cookies when requesting static files.
As an aside, if your site uses cookies (or ASP.NET sessions,
which uses cookies), you should never allow visitors to access your pages
without a subdomain. That is, don't allow them to access http://mydomain.com/page.aspx.
Otherwise, if a visitor first accesses http://www.mydomain.com/page.aspx
(using subdomain www), sets a cookie, and then comes
back via http://mydomain.com/page.aspx (no
subdomain), the browser won't send the cookie! IIS 7 makes it very easy to
redirect requests to http://mydomain.com to http://www.mydomain.com using an entry
in web.config. See Microsoft's iis.net (http://www.iis.net), or the image
control adapter included in chapter 12 of my book ASP.NET Site Performance
Secrets (https://www.packtpub.com/asp-net-site-performance-secrets/book ).
Parallel loading
When a browser loads a page, it loads the static files (images,
JavaScript files, CSS files) in parallel to reduce the visitor's wait time.
However, the browser limits the number of files that are loaded in parallel. Modern
browsers (IE7 and better, Firefox, Chrome, Safari) have a limit of about 6,
while older browsers (such as IE6) have a limit of 2.
However, this limit is per (sub)domain. It isn't per IP
address. This means that if you spread your static files over for example 2
cookieless domains, you allow the browser to load up to two times more files in
parallel.
Using cookieless domains on your site
If you add a cookielessDomains
element with one or more domains to the combineAndMinify
element, the package adds those domains to the urls of all static files in your
site. This includes images referenced from CSS files.
This means that if you use:
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain=“http://static1.mydomain.com”/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
Then for example
<img src=“images/ball3.png” height=“10” width=“10” />
is replaced by
<img src=“http://static1.mydomain.com/images/ball3.png” height=“10” width=“10” />
If you define multiple domains, such as:
<configuration>
...
<combineAndMinify ... >
<cookielessDomains>
<add domain=“http://static1.mydomain.com”/>
<add domain=“http://static2.mydomain.com”/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
Then the package attempts to spread the files over the
available domains (note that you can add more than 2 domains if you want). This
to get the browser to load more files in parallel. So if you have these image
tags:
<img src=“images/ball3.png” />
<img src=“images/woodentoy4.png” />
You would wind up with:
<img src=“http://static2.mydomain.com/images/ball3.png” />
<img src=“http://static1.mydomain.com/images/woodentoy4.png” />
To create the subdomains, log into your account at your domain
registrar and create the static1, static2,
etc. subdomains (you can use any subdomain names you like). Make sure they
point to the same IP address as your www subdomain.
This way, you don't have to physically move your static files. Note that every
subdomain that is not your www subdomain acts as a “cookieless”
subdomain - it isn't like there are special “cookieless” subdomains as such.
Contrary to what you may think, if you have say 2 cookieless
domains, the package won't use one domain for half the static files and the
other domain for the other half. This is because it needs to make sure that on
every page, a given static file is always given the same domain. If images/ball3.png were turned into http://static1.mydomain.com/images/ball3.png
on one page, but to http://static2.mydomain.com/images/ball3.png
on a second page, than the browser won't find ball3.png in its cache when it
hits the second page, even if it stored ball3.png when it accessed the first
page. Because of the different domains, it would regard the two urls as
different, even though they actually point at the same resource.
Because of this requirement, the package uses the hash code
of the file name to work out which domain to use. So if there are two domains, than
if the hash is even it uses the first domain, and if it is odd it uses the
second domain. Because it is unlikely that 50% of file names have an even hash
code, you are unlikely to get a perfect distribution of the static files over
the available domains.
enableCookielessDomains
Determines whether cookieless domains are used.
Value
|
Description
|
Never
|
Cookieless domains are never used.
|
Always
(default)
|
Cookieless domains are always used, provided that 1) the
package is active, and 2) you have defined a cookielessDomains
element with cookieless domains.
|
ReleaseModeOnly
|
Cookieless domains are only used in release mode.
|
DebugModeOnly
|
Cookieless domains are only used in debug mode.
|
Example
<configuration>
...
<combineAndMinify active=“Always” enableCookielessDomains=“ReleaseModeOnly” >
<cookielessDomains>
<add domain=“http://static1.mydomain.com”/>
<add domain=“http://static2.mydomain.com”/>
</cookielessDomains>
</combineAndMinify>
...
</configuration>
This option is really only useful if you decide to activate
the package in your development environment. In that case, you may decide to
only use cookieless domains in release mode, while using all the other features
of the package in both release and debug mode.
The reason for this is that if you have new images in your
development environment that are not yet on your live site, than they won't
show up in your development environment if you use the cookieless domains -
which point to your live site.
If you want to take that route, set enableCookielessDomains
to ReleaseModeOnly.
The default value for enableCookielessDomains
is Always. However, keep in mind that for the package
to use cookieless domains, it has to be active. And by default, it is only
active in release mode.
makeImageUrlsLowercase
Determines whether the package makes all image urls
lowercase.
Value
|
Description
|
true
|
All images urls are converted to lowercase
|
false
(default)
|
Images url casing is left as it is
|
Example
<configuration>
...
<combineAndMinify makeImageUrlsLowercase=“true” >
</combineAndMinify>
...
</configuration>
You may be using inconsistent casing in your web pages to
refer to the same image. For example:
<img src=“/images/woodentoy4.png” height=“10” width=“10” />
...
<img src=“/images/WoodenToy4.png” height=“10” width=“10” />
Assume a browser or proxy loads woodentoy4.png
and stores it in its cache. When it then needs to load WoodenToy4.png,
it may not recognize it is the same as the woodentoy4.png
that it already has in cache, and send a superfluous request for WoodenToy4.png.
To prevent this, set makeImageUrlsLowercase
to true. This way, all images urls in the HTML and
CSS sent to the browser will be lowercase, so there is no inconsistent casing. Note
that the package doesn't change your source files. Instead, it changes the HTML
that gets generated from your source files and sent to the browser.
insertVersionIdInImageUrls
Determines whether the package 1) inserts version ids in
image file names and 2) allows the browser to cache images for up to a year.
Value
|
Description
|
true
|
Version ids are inserted in image file names. Requires
changes to web.config (see below).
|
false
(default)
|
No version ids are inserted in image file names
|
Example
<configuration>
...
<combineAndMinify insertVersionIdInImageUrls=“true” >
</combineAndMinify>
...
</configuration>
When a browser receives an image, it stores it in its browser
cache. That way, if it needs to load the image again, it may still be in cache,
so there is no need to send a request to the server. The result is less waiting
for the visitor and less bandwidth used by your server.
One issue here is how long the browser should keep the image
in its cache. Too long, and you may have visitors looking at outdated images.
Too short, and the browser sends more requests for the image than necessary.
By setting insertVersionIdInImageUrls
to true, you get the best of both worlds:
·
It causes the package to send HTTP Response Headers when sending
images that tell the browser it can cache the image for up to a year - the
maximum you can ask for according to the HTTP specification.
·
And it inserts a version id into the image file name as used in
image tags (both in the page HTML and in the CSS). The package calculates that
version id from the last update time of the image file - so if you update an
image, the version id changes. That way, when you update an image, the browser
immediately picks up the new image. It won't pick up the image it has in cache,
because that has a file name with the old version id.
A few more details about how this feature works:
·
The package only inserts the version id in the tags that are
sent to the browser. The file names of your images on disk stay the same.
·
There is no need to change your image file names manually. When
the browser sends a request for an image, the image file name will have the
version id. But the package takes care of stripping out the version id and
serving the correct image to the browser.
·
To find out the version id, the package needs to access the file
system to find out the last update time of the image file. You don't want this
to happen for each request, so the package stores the version ids in server
cache. These cache entries are invalidated the moment the underlying file
changes, so the cache is never outdated.
·
Why insert the version id in the file name? Why not just add it
as a query string? That would be a bit easier to handle. However, proxies
(intermediate servers that pass on messages on the Internet) are less likely to
cache files with query strings. So by inserting the version id in the file name
instead of using a query string, you gain maximum proxy caching.
·
There is no counterpart of insertVersionIdInImageUrls
for JavaScript and CSS files, because the package always uses version ids and
long term caching for those files.
Additional Installation
Now that the package inserts a version id in the image file
names used in image tags, the browser will send requests for file names with
version ids. Those file names won't match actual image files on your server,
because they don't have the version ids. To solve this, you need to get the
package to handle incoming requests for images, so it can remove the version id
and load the correct file.
Additional Installation for IIS 7
Take these steps if you use IIS 7 for your live site, and
also if you use the package in your development environment.
In the installation instructions for IIS 7 for the entire
package, you modified your web.config file to get the HTTP Handler to handle
.js and .css files.
Now change web.config again, so the HTTP Hander also handles
.gif, .png and .jpg files:
</configuration>
...
<system.webServer>
<validation validateIntegratedModeConfiguration=“false”/>
...
<handlers>
...
<!-- required for insertVersionIdInImageUrls attribute -->
<add name=“GifHandler” verb=“*” path=“*.gif”
type=“CombineAndMinify.HttpHandler, CombineAndMinify” resourceType=“Unspecified”/>
<add name=“PngHandler” verb=“*” path=“*.png”
type=“CombineAndMinify.HttpHandler, CombineAndMinify” resourceType=“Unspecified”/>
<add name=“JpegHandler” verb=“*” path=“*.jpg”
type=“CombineAndMinify.HttpHandler, CombineAndMinify” resourceType=“Unspecified”/>
<!-- required for all features -->
<add name=“JavaScriptHandler” verb=“*” path=“*.js”
type=“CombineAndMinify.HttpHandler, CombineAndMinify” resourceType=“Unspecified”/>
<add name=“CssHandler” verb=“*” path=“*.css”
type=“CombineAndMinify.HttpHandler, CombineAndMinify” resourceType=“Unspecified”/>
</handlers>
...
</system.webServer>
...
</configuration>
Additional Installation for IIS 6 or IIS
7 in classic mode
Follow these steps if your live site uses IIS 6. If your
live site uses IIS 7 or higher, you can skip this.
1.
In the installation instructions for IIS 6 for the entire package, you
modified your web.config file to get the HTTP Handler to handle .js and .css
files.
Now change web.config again, so the HTTP Hander also handles
.gif, .png and .jpg files:
<configuration>
...
</system.web>
...
<httpHandlers>
...
<!-- required for insertVersionIdInImageUrls attribute -->
<add verb=“*” path=“*.gif” type=“CombineAndMinify.HttpHandler,
CombineAndMinify” />
<add verb=“*” path=“*.png” type=“CombineAndMinify.HttpHandler,
CombineAndMinify” />
<add verb=“*” path=“*.jpg” type=“CombineAndMinify.HttpHandler,
CombineAndMinify” />
<!-- required for all features -->
<add verb=“*” path=“*.js” type=“CombineAndMinify.HttpHandler,
CombineAndMinify” />
<add verb=“*” path=“*.css” type=“CombineAndMinify.HttpHandler,
CombineAndMinify” />
</httpHandlers>
...
</system.web>
...
<configuration>
2.
In the installation instructions for IIS 6, you also saw how to route
all requests for .js and .css
files to ASP.NET. Now use the same instructions to do the same for these
extensions:
·
.gif
·
.png
·
.jpg
For a lot more on browser caching and proxy caching, see www.iis.net (http://www.iis.net) or chapter 12 of
my my recently released book ASP.NET Performance Secrets
(https://www.packtpub.com/asp-net-site-performance-secrets/book).
exceptionOnMissingFile
Determines whether the package throws an exception when an
image file is missing.
Value
|
Description
|
Never
(default)
|
The package never throws an exception when an image file
is missing.
|
Always
|
The package always throws an exception when an image file
is missing.
|
ReleaseModeOnly
|
The package only throws an exception if the site is in
release mode.
|
DebugModeOnly
|
The package only throws an exception if the site is in
debug mode.
|
Example
<configuration>
...
<combineAndMinify exceptionOnMissingFile=“DebugModeOnly”
insertVersionIdInImageUrls=“true” >
</combineAndMinify>
...
</configuration>
Assume insertVersionIdInImageUrls
is set to true, so the package inserts a version id
in all image urls. This means it has to access each image file to find its last
updated time. What happens if the image file cannot be found? That is
determined by the exceptionOnMissingFile attribute:
·
If exceptionOnMissingFile is active
(see table above) and the package finds that an image file cannot be found, it
throws an exception with the path of the image. That makes it easier to find
missing images.
·
If exceptionOnMissingFile is not
active, the package doesn't throw an exception but recovers by not inserting a
version id in the image url.
If all images should be present in your development
environment, than it makes sense to set exceptionOnMissingFile
to DebugModeOnly. That way, you quickly find broken
images while developing your site, while preventing exceptions in your live
site where you probably prefer a broken image over an exception.
What about JavaScript and CSS files? The package accesses
these files when combining and / or minifying them:
·
If exceptionOnMissingFile is active
and a JavaScript or CSS files can't be found, you'll get an exception, just as
with images.
·
If exceptionOnMissingFile is not
active and a JavaScript or CSS files can't be found, it just writes a comment
in the combined and / or minified file, specifying the full name of the file
that couldn't be found.
Keep in mind that if you want exceptions while the site is
in debug mode, you have to ensure that the package is actually active in debug
mode - set active to Always
to make that happen.
removeWhitespace
Determines whether the package removes superfluous white
space and comments from the HTML of the page.
Value
|
Description
|
true
|
Superfluous white space and comments are removed.
|
false
(default)
|
No superfluous white space and comments are removed.
|
Example
<configuration>
...
<combineAndMinify removeWhitespace=“true” >
</combineAndMinify>
...
</configuration>
When you set removeWhitespace to true, the package removes all HTML comments from the page
and collapses all runs of white space into a space. However, if a run of white
space contains one or more line breaks, it is collapsed into a line break. That
way, inline JavaScript will not be broken.
headCaching
Determines how tags for combined JavaScript files and CSS
files are cached.
Value
|
Description
|
None
(default)
|
Caching of replacement tags is switched off.
|
PerSite
|
There is a single cache entry for the entire site.
|
PerFolder
|
There is a cache entry per folder.
|
PerPage
|
There is a cache entry per page (ignoring any query
string).
|
PerUrl
|
There is a cache entry per url (including any query
string).
|
Example
<configuration>
...
<combineAndMinify headCaching=“PerSite” >
</combineAndMinify>
...
</configuration>
Even though the package caches all minified and combined files,
there is still some work involved in replacing tags of individual JavaScript
files and CSS files with tags of combined files. Without further caching, this
needs to be done for each page request.
To reduce the CPU usage involved in this, the package
provides the option to cache the replacement tags. The recommended way to do
this depends on the way you load your JavaScript and and CSS files:
Situation
|
Recommended
Value
|
The additional CPU usage of the package is not an issue. Or
the tags to load JavaScript and CSS files are totally ad hoc per page.
|
None
(default)
|
All pages load the same JavaScript and CSS files in the
same order. For example, all pages uses a single master page, and the
master page has all the script and link tags to load the JavaScript and CSS
files.
|
PerSite
|
Your pages are split over folders, and the JavaScript and
CSS files you load depend on the folder. For example, pages in the admin folder all load the same JavaScript and CSS files
in the same order, but those files are different from the ones loaded by
pages in the products folder.
|
PerFolder
|
Each page loads different JavaScript and / or CSS files.
However, the query string doesn't influence which files are loaded. So toys.aspx?id=1 and toys.aspx?id=2
load the same files in the same order, but categories.aspx
loads different files.
|
PerPage
|
The JavaScript and CSS files used by a page depend on the
entire url, including its query string. So toys.aspx?id=1
and toys.aspx?id=2 load different files.
|
PerUrl
|
The headCaching attribute really
comes into its own if you load JavaScript and CSS files from a master page or a
shared user control. This is because the package caches entire groups of tags, and
the tags to replace those groups with. This process is sensitive to for example
white space in between tags. That means that
<script type=“text/javascript” src=“/js/script1.js” ></script>
<script type=“text/javascript” src=“/js/script2.js” ></script>
and
<script type=“text/javascript” src=“/js/script1.js” ></script>
<script type=“text/javascript” src=“/js/script2.js” ></script>
are not the same, due to the extra white line in the second
block.