Blog

Best Nikon Remotes

Jan 07, 2009 by:   Tim Stanley

Which remote works with which Nikon? Most new Nikon cameras don't come with a remote control.  Some camera bodies will work with multiple remotes (wired and wireless), but unlike the legendary Nikon interchangeable lenses, the remotes don't switch between camera bodies so easily.  Here's a quick guide on which remotes work with which cameras and what's the best Nikon remote for your camera.

I've listed compatibility where I could find information on the remotes and cameras. Please check the camera user guide to ensure the remote is compatible with your camera before purchasing the remote. All of these remotes can be found at B&H Photo.

If it works with your camera, the ML-L3 wins the prize for the best remote.  It's cheap and it works with most Nikon cameras.

All photos courtesy Nikon. All prices are as of January 2009.

ML-L3

4730_ML-L3-Wireless-Remote-Control-(Infrared) 

The ML L3 is a wireless infrared remote.  The camera must be switched to "remote shutter mode" to allow the remote to operate with the camera.  There are no instructions with the remote.  Check your camera user guide for any instructions (Page 38 for D80 users).  Works in timer delay, and non timer delay mode (the manual calls this quick response mode).  When set for bulb exposure, press once to activate and a second time to release.  There must be a clear line of sight from the remote to the camera. It comes with a small case that can attach to the neck strap.  The required CR-2025 3v battery comes with the remote.

The D80 when set to "remote" shutter mode,  by default will revert to the normal shutter mode after a period of time (about 60 seconds) if the remote hasn't been pressed.  This can get confusing if you wait too long to fire shots using the remote.  This can be altered changing the Remote on duration to a longer value (1 min., 5 min., 10 min. or 15 min.).

If you use bulb exposure, I recommend setting the Exp. delay mode to on.  This helps remove any vibration caused by the shutter opening.

Price And Compatibility: ML-L3 $16.95: D90, D80, D60, D50, D40x, D40, D70, D70s, N65, N75, F65, Pronea S, Nuvis S, Lite Touch 110s, 130 ED, Coolpix 8400, Coolpix 8800

MC-DC1

25326-MC-DC1_Remote_Release_front

The MC-DC1 remote is a wired remote with a small USB type connector on the end.  It has the ability to lock in place to keep a shutter open for long exposures.   On the D80, simply plug it in and press the button.  The camera does not have to be in any special mode to operate it.  The MC-DC1 has the ability to press and hold and lock to set the exposure so you don't have to keep the button pressed.  Great for those starry night sky shots.

If you use bulb exposure, I recommend setting the Exp. delay mode to on.  This helps remove any vibration caused by the shutter opening.

The remote comes in two similar but different versions, the MC-DC1 and MC-DC2. What's the difference between the MC-DC1 and MC-DC2?  I don't know, but reports are they are not cross compatible (i.e. the MC-DC2 will not work on the D80 and MC-DC1 will not work on the D90).

Price And Compatibility: MC-DC1 $24.95: D80, D70s

MC-DC2

25395_MC-DC2-Remote-Cord_front

Just like the MC-DC1, but for the Nikon D90.  Reportedly does not work on the D80.  As of early 2009, the MC-DC2 is hard to find in stock.

Price And Compatibility: MC-DC2 $26.95: D90

MC-36

 

4917_MC_36_Multi_Function_Remote_Cord_front

The MC-36 is 10 pin remote and also will work as a timer and an intervalometer for time lapse photography.

Price And Compatibility: MC-36 $129.95: D3X, D700, D300, D3, D200, D100, F6, F5, F100, N90, D2 series, D1 series

ML-3

4645_ML-3-Modulite-Remote-Control-Set_front

Not to be confused with the ML-L3, this is a 10 pin remote with infrared wireless.  This can fire shots, remotely or if something passes between the transmitter and the receiver (for surveillance wildlife photography).

Price And Compatibility: ML-3 $169.95: D3X, D700, D300, D3, D200, D100, F6, F5, F100, N90, D2 series, D1 series

MC-30

4660_MC-30-Remote-Trigger-Release_front

Another 10 pin remote, but wired.  Has a lock/hold capability.

Price And Compatibility: MC-30 $54.95: D3X, D700, D300, D3, D200, D100, F6, F5, F100, N90, D2 series, D1 series

MC-22 Remote Cord

4652_MC-22-Remote-Cord-with-Banana-Plugs_front

Not really a remote, but a cable with connectors to allow building your own remote or hooking it to other equipment.  This is a 10 pin connector.

Price And Compatibility: MC-22 cord $49.95, : D3X, D700, D300, D3, D200, D100, F6, F5, F100, N90, D2 series, D1 series

References

Related Items

Office Accounting Express 2009

Nov 24, 2008 by:   Tim Stanley

Microsoft has a great deal for small business with a free version of Accounting Express 2009.  It can create estimates, invoices, track customer payments, set product and service pricing and can export and import data using Microsoft Excel formats, and can export to e-mails, Microsoft Word documents, or PDF files, and even sell items on eBay.

You can compare Microsoft Accounting 2009 versions to see if you would like the professional version which includes additional report, multi-user access, and the ability to track and bill for employee time. I've found the free Accounting Express 2009 version combined with the PayPal Outlook add-in provides everything I need.  It does require Microsoft office.

I looked at Fresh Books and Blinksale, but Accounting Express 2009 provides the greatest functionality for the free cost.

Download Office Accounting Express 2009.

image

References

Related Items

Website Tags As Images

Oct 17, 2008 by:   Tim Stanley

Sala has an interesting application (Java Applet) that will display the tags of a specific  Website as a graph or image.  The images are generated from the tags for a specific web page.

The link to create a new graph of a specific URL is: http://www.aharef.info/static/htmlgraph/

The dots generated have specific color codes to indicate the types of tags on the site. A collection of sites and images are posted on Flickr with the tag websitesasgraphs.

  • blue: for links (the A tag)
  • red: for tables (TABLE, TR and TD tags)
  • green: for the DIV tag
  • violet: for images (the IMG tag)
  • yellow: for forms (FORM, INPUT, TEXTAREA, SELECT and OPTION tags)
  • orange: for line breaks and block quotes (BR, P, and BLOCKQUOTE tags)
  • black: the HTML tag, the root node
  • gray: all other tags

An image generated of http://tim-stanley.com.

Graph of tim-stanley.com

Related Items

Silverlight 2.0 Released

Oct 15, 2008 by:   Tim Stanley

On October 14, 2008, Microsoft released Silverlight 2.0, the cross-platform browser plug-in for both Macintosh and PC platforms.

Silverlight includes several Rich Internet Application (RIA) features, including:

  • WPF UI Framework
  • Rich Controls
  • Rich  Networking Support
  • Rich Base Class Library

The controls include TextBox, CheckBox, RadioButton, ComboBox, StackPanel, Grid, Panel, Slider, ScrollViewer, Calendar, DatePicker, DataGrid, ListBox, and others.

Downloads are available at:

References

Related Items

BlogEngine.Net Expanding Categories And Tags

Oct 06, 2008 by:   Tim Stanley

BlogEngine.Net provides the ability to selectively disclose information in the blog postings based on the configuration settings.  I took Dave Burke's concept on the Flexible Post Excerpt Display and expanded it to include expansion of all categories and tags even if the ShowDescriptionInPost setting was set to true.

BlogEngine.Net expands data in a blog as follows:

  1. ShowDescriptionInPost = true, shows the content in the description of the blog followed by .
  2. ShowDescriptionInPost = false, BreakPost extension enabled, shows the content of the blog entry until the tag followed by the text [..more].
  3. ShowDescriptionInPost = false, BreakPost extension disabled, shows the content of the entire blog entry.

The new logic will override these settings and expand the category and tags, but still take into account the BreakPost extension logic.  If the description isn't present, the first 300 characters of the post are used.

Recommended Best Practices

  1. Always place a good description in the entry description section (excerpt).
  2. Always place a tag around the first or second paragraph at the beginning of the entry.

The description section doesn't allow for formatted HTML or images, but expanding the description until the tag does.

Core BlogSettings.cs changes

Add ExpandCategories and ExpandTags properties.


/// 
/// Expand categories if true. 
/// Overrides showDescriptionInPostList.
/// 
public bool ExpandCategories
{
    get { return expandCategories; } 
 
    set { expandCategories = value; }
}
 
/// 
/// Expand tags if true. 
/// Overrides showDescriptionInPostList.
/// 
public bool ExpandTags
{
    get { return expandTags; }
 
    set { expandTags = value; }
}

Admin Settings.aspx.cs Changes

Add the ability to update the new properties via the Admin Settings page.


BlogSettings.Instance.ExpandCategories = cbExpandCategories.Checked;
BlogSettings.Instance.ExpandTags = cbExpandTags.Checked;
 
// In BindSettings()
cbExpandCategories.Checked = BlogSettings.Instance.ExpandCategories;
cbExpandTags.Checked = BlogSettings.Instance.ExpandTags;
 
// In btnSave_Click()
BlogSettings.Instance.ExpandCategories = cbExpandCategories.Checked;
BlogSettings.Instance.ExpandTags = cbExpandTags.Checked;

Admin Settings.aspx.cs Changes


<label for="<%=cbExpandCategories.ClientID %>">Expand Categories</label>
<asp:CheckBox runat="server" ID="cbExpandCategories" /><br />
 
<label for="<%=cbExpandTags.ClientID %>">Expand Tags</label>
<asp:CheckBox runat="server" ID="cbExpandTags" /><br />

User controls/PostList.ascx.cs Changes

Use the logic for the new properties at display time (PostList).


postView.ShowExcerpt = BlogSettings.Instance.ShowDescriptionInPostList;
bool isCategoryPostList = false;
bool isTagPostList = false;
if (HttpContext.Current.Request.RawUrl.IndexOf("category") != -1)
{ 
    isCategoryPostList = true;
    postView.ShowExcerpt = !BlogSettings.Instance.ExpandCategories;
}
if (HttpContext.Current.Request.RawUrl.IndexOf("tag") != -1)
{
    isTagPostList = true;
    postView.ShowExcerpt = !BlogSettings.Instance.ExpandTags;
}

References

Related Items

Common HTML Markup

Oct 04, 2008 by:   Tim Stanley

Everyone that writes content on the web should know a little HTML.  This is my cheat sheet for the most common used HTML elements I've seen that are supported in multiple browsers, tools, and CMS software.

Text Structure

blockquote, br, h1, h2, h3, h4, h5, h6, p

Example:

A pessimist is one who makes difficulties of his opportunities and an optimist is one who makes opportunities of his difficulties.

Harry S. Truman


<blockquote cite="http://www.brainyquote.com/quotes/authors/h/harry_s_truman.html">
    <p>A pessimist is one who makes difficulties of his opportunities 
    and an optimist is one who makes opportunities of his difficulties.</p>
    <p>Harry S. Truman</p>
</blockquote>

HTML Elements

a, abbr, acronym, code, del, em, ins, img, pre, sub, sup, strike, strong

Notes:

  • The image element (img) should include an alt="" attribute that is a description of the image.
  • Declining in use; b (use strong),  i (use em).
  • The element strike could be used for formatting, but if used to denote editing, del should be used instead.

Example:

HTML or HTML 4.01 is an abbreviation, whereas, GUI is an acronym. I added text then removed it.


<p>
    <abbr title="Hyper Text Markup Language">HTML</abbr> or <a title="HTML 4.01 Specification" 
    href="http://www.w3.org/TR/html4/">HTML 4.01</a> is an abbreviation, 
    whereas, <acronym title="Graphical User Interface">GUI</title> is an acronym. 
    I <ins>added</ins> text then <del>removed</del> it. </acronym>
</p>

Lists

dldt, dd, li, ol, ul

Example:

  • apples
  • peaches
  • pears

<ul>
    <li>apples</li>
    <li>peaches</li>
    <li>pears</li>
</ul>

Tables

caption, tabletdthtr

Grouping: tbody, thead, tfoot

Example:

Column One Column Two
cell one cell two
cell three cell four
Table caption

<table>
   <tr>
      <th>Column One</th>
      <th>Column Two</th>
   </tr>
   <tr>
      <td>cell one</td>
      <td>cell two</td>
   </tr>
   <tr>
      <td>cell three</td>
      <td>cell four</td>
   </tr>
<caption>Table caption</caption>
</table>

Content Formatting

br, div, hr, span

Elements To Avoid

center, font, s, u

Style Preferences

br, div, hr, span, img

Personally, I don't like br tags.  If more space is needed between paragraphs, then the CSS should be modified, not the content. I prefer div elements for block sections and span elements for inline.

Example:

Snowmobiles at Keystone Colorado

I went on a snowmobile tour in Keystone Colorado.


<div class="floatleft">
    <img alt="Snowmobiles at Keystone Colorado"  
    src="http://tim-stanley.com/Snowmobile1_thumb.jpg">
</div>
<p>I went on a snowmobile tour in Keystone Colorado.</p>
<div class="clearer></div>

Head Elements

link, meta, script, style, title

 

The meta description is used to display by search engines.  If a description isn't present, the search engine will pick their won.  Most search engines use a combination of the description and content to display preview information of the page.

Version information on style sheets and JavaScript files are used and updated when the content changes to force browsers to re-load their cached versions (particularly if a far expiration date is set on the content).

Example:


<head profile="http://gmpg.org/xfn/11">
    <link rel="stylesheet" href="/themes/style.css&amp;v=1.4.5.1" type="text/css" />
    <meta name="keywords" content="photography,photoshop" />
<meta name="description" content="Mister Retro has a great set of Photoshop plug-in's that
    will save a significant amount of time and effort when manipulating files in Photoshop for 
    those textured and stunning artistic effects." />
    <link rel="last" title="Using Cache And Compression For Performance" 
        href="/post/Using-Cache-And-Compression-For-Performance.aspx" />
    <link rel="first" title="How To Enable HTM Server Side Include Parsing in IIS" 
        href="/post/How-To-Enable-HTM-Server-Side-Include-Parsing-in-IIS.aspx" />
    <link rel="next" title="Images Part 1 - Snagit" href="/post/Images-Part-1-Snagit.aspx" />
    <link rel="prev" title="Font Tools" href="/post/Font-Tools.aspx" />
    <link rel="contents" title="Archive" href="/archive.aspx" />
    <link rel="start" title="Tim-Stanley.com" href="/" />
    <link type="application/rdf+xml" rel="meta" title="SIOC" href="http://tim-stanley.com/sioc.axd" />
    <link type="application/apml+xml" rel="meta" title="APML" href="http://tim-stanley.com/apml.axd" />
    <link type="application/rdf+xml" rel="meta" title="FOAF" href="http://tim-stanley.com/foaf.axd" />
    <link type="application/rss+xml" rel="alternate" title="Tim-Stanley.com (RSS)" 
        href="http://tim-stanley.com/syndication.axd?format=rss" />
    <link type="application/atom+xml" rel="alternate" title="Tim-Stanley.com (ATOM)"
        href="http://tim-stanley.com/syndication.axd?format=atom" />
    <link type="application/rsd+xml" rel="edituri" title="RSD" href="http://tim-stanley.com/rsd.axd" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link type="application/opensearchdescription+xml" rel="search" title="Tim-Stanley.com"
        href="http://tim-stanley.com/opensearch.axd" />
    <script type="text/javascript" src="/blog.js&amp;v=1.4.5.1"></script>
    <title>Machine Wash Effect - Tim-Stanley.com </title>
</head>

DocType

The DOCTYPE is the most controversial.  XHTML or HTML, transitional, or strict?  The main reason the DOCTYPE is controversial is because it can cause browsers to display in standard or quirks mode depending on the DOCTYPE. XHTML 1.0 Transitional is my preference.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

References

Related Items

Using Cache And Compression For Performance

Sep 24, 2008 by:   Tim Stanley

Most browsers and servers have default values that provide fairly good performance with a minimum caching of static file content.  A little bit of coaxing can result in better performance with less traffic and less bandwidth.

There are two types of caching I discuss: static content  (*.JPG, *.JPEG, *.png, *.gif, *.ico) rarely updated and semi-static content (*.js, *.css) updated very infrequently.  The decision to cache page output (*.aspx, *.html, *.htm) long term is too dependent on application functionality decisions to discuss generically.

Summary

If you are short on time, the quick summary is summarized below.

Setting a future expiration date let's the browser be smarter about how it requests content only when absolutely necessary.  Compressing / Deflating the content for css, js, aspx and html content minimizes the amount of bandwidth used.  If you pay for bandwidth by the byte, compression is going to save money.

Windows Servers:

  1. If you have access to the IIS Admin console, set an expiration date.  This is cheap and quick.  You get caching via future expiration dates without compression and with no code changes.
  2. If you want to control individual files for compression and/or caching, but do not have IIS Admin access, you can configure a verb to process *.css.axd, *.jpg.axd, *.js.axd files and then change your references to the content.
  3. If you want to control individual files for compression and/or caching, install an httpHandler and configure the verb to process *.css, *.jpg, *.js or other files.  This also requires access to the IIS Admin console to set the  Application Extension Mapping, or if the project is installed via MSI, the mappings can be done at installation.

Apache Servers:

  1. Use Apache mod_expires to set the expiration date in the future.
  2. Modify .htaccess and set  Header unset ETag and FileETag None
  3. Use a compression module on like mod_gzip or something similar.

Expiration Dates:

  1. Images should be anywhere from 30 days to 5 years or more.
  2. CSS and JavaScript may need to be updated more frequently and should be anywhere from 1 day to 5 days.

One Page, Many Contents

When loading a web page, it typically isn't a single request.  It's just the tip of the iceberg.  The page loads, then the browser may need to load more content from that (like a CSS file that references images). The browser may also attempt to load the favicon.ico file even if the page doesn't ask to load it.

Here's an example of a single page that has 27 requests for various different content needed to support loading 1 page.

Cache 200

200's and 304's

Browsers have a conversation with the server to request content for a [url] that starts off something like this.

First time requests:

  1. Browser: Can I have the content for [URL]?
  2. Server: HTTP/1.0 200 OK -> here it is.
  3. Browser: I also need the content for [URL]
  4. Server: HTTP/1.0 200 OK -> here it is.
  5. Browser: I also need the content for [URL]
  6. Server: HTTP/1.0 200 OK -> here it is.

That happens over and over for every piece of content needed for the page to be displayed for the first time.  The second time the request is made, if the browser has enough information to make a decision, it gets a bit smarter.

Second + N requests:

  1. Browser: If the server sent an expiration time for the content, the browser may just use the last copy of the content (No request sent to the server)
  2. Browser: If the server didn't send an expiration time, request the content (depends on browser settings).
  3. Server: If it was updated or no eTag match: HTTP/1.0 200 OK -> here it is.
  4. Server: If it's the same: HTTP/1.1 304 Not Modified -> Use what you have, it's hasn't changed.

Cache 200 2nd

The difference between loading the same page shown above is 1.78 seconds for the first time and 0.108 seconds the second time. The time savings is due to the fact that all but one piece of content is cached in the browser for the second request.

Browser Settings

Although you can't force users to do it, browser settings can affect how they ask servers for the information.

A unique query parameter on a URL will cause IE 7 to believe it's a "different" URL and IE will be more inclined to request data even though it already has it.  For example traces I've seen with timestamp's as part of the query parameter will cause IE to request JPG files and receive 304 responses.  If the query parameter is not part of the URL, IE will not request the content again until a refresh is requested.

The following value controls how IE uses it's cache for HTTP content (not just pages).

IE History Settings

 

Firefox 3 has both the Private Data (cache) setting and the options that control how it utilizes the cache.

Firefox Private Data

Firefox Options

Entity Tags

Entity Tags (ETags) are used to provide additional detail for checking caching.  Yahoo Rules for high performance web sites and YSlow recommend setting the ETag values to improve performance.

By default, Apache and IIS use ETags. If you are running a web farm, remove ETags or ensure the ETags are syncronized across the farm (refer to the Microsoft support article to remove etags in IIS).

In Apache to remove ETags, modify the .htaccess or httpd.conf file:


Header unset ETag
FileETag None

If ETags are used, the request from the browser will contain something like the following:

If-Modified-Since: Tue, 08 Jul 2008 05:52:56 GMT
If-None-Match: "0ac6adebee0c81:893"

In ASP.Net code, this is set with a statement like:


Response.Cache.SetETagFromFileDependencies();

Refer to the Microsoft support article to remove etags in IIS or to set ETags, refer to  Enabling Client-Side Caching of Generated Content in ASP.NET for a more detailed explanation.

Save Requests, Use A Cache

If you have a large number of users, the 304 responses add additional HTTP requests and traffic.  These can be eliminated or reduced in IIS and ASP.Net in three ways: IIS Content Expiration, ASP.Net *.css httpHandlers, or with an ASP.Net *.axd httpHandler.

IIS Content Expiration

If you have access to IIS administration set the IIS expiration cache to an appropriate value.  Unlike Apache, I haven't figured out how to set different expiration dates for images versus CSS and JavaScript files.

IIS Content Expiration

 

ASP.Net httpHandler *.css.ashx *.css.axd

Sample content references:

<link rel="stylesheet" type="text/css" href="csshandler.axd?path=style.css" mce_href="csshandler.axd?path=style.css" />
<link rel="stylesheet" type="text/css" href="style.css.axd" mce_href="style.css.axd" />

Adding an httpHandler in the web.config.


<httpHandlers>
    <add path="*.css.axd" verb="*" type="Utils.SFHandler" validate="false"/>
</httpHandlers>

The article at Caching in ASP.NET explains in more detail how to use this approach.  This approach does not require IIS administration permissions, but it does leave the CSS or other source references tied to unusual file extensions for css, js, and images.

Caution: You must take measures to ensure that only specific types of files desired are output.  If this is not done properly in code, using the path=abc.css approach, could allow someone to load a normally secure file (like the web.config) using this technique.

Once you have the handler in place, it's simple:


Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 86400 ) )
Response.Cache.SetCacheability ( HttpCacheability.Public )

 

Refer to the code example for the BlogEngine.Net CSS handler for more detail.

ASP.Net httpHandler *.css

Sample content reference:

<link rel="stylesheet" type="text/css" href="style.css" mce_href="style.css" />

Adding an httpHandler in the web.config.


<httpHandlers>
    <add path="*.css" verb="*" type="Utils.SFHandler" validate="false"/>
</httpHandlers>

The approach is exactly the same as in Caching in ASP.NET, but this time some more configuration work is required.  However, with this approach an additional application IIS Extension Mapping is required.  If you have access to the IIS administration console, this is easy for the site.  If you are in a commercial hosting environment, it's much more difficult.

In IIS, this is set on the Home or Virtual Directory, Configuration, Mappings, Add

IIS App Config

IIS App Config Add

Executable = C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
Extension = .css
Limit To = GET,HEAD,POST,DEBUG

Apache mod_expires

In Apache, an future expiration date can be set with with Apache mod_expires.


ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000

Save Bandwidth, Use Compression

Compression can reduce the size of a css, js or the output of php or aspx files by 60-80%. Yahoo performance research notes:

40-60% of Yahoo!’s users have an empty cache experience and ~20% of all page views are done with an empty cache.

 

Even though these files can be cached, by enabling compression for these files, you reduce both the bandwidth and the load time required for the file.  If you pay for bandwidth by the byte, this will save money.

All this bandwidth savings comes at a cost of CPU.  If the results for static content are cached, the result is minimal.  If you have a large number of users accessing a site and they are accessing it over the WAN, not LAN, then compression is in my opinion a better option over the CPU cost.  If your on a LAN or have a low number of users, compression isn't going to benefit compared to the CPU cost.

Mads Kristensen talks about stripping white spaces in the article Reduce the weight of stylesheets by 35% at runtime but his article on HTTP compression in ASP.NET 2.0 covers how to make compression work for the ASPX output and this can be applied to css and js files as well.

Warning: Using compression can break some javascripts, if used on the Webresources.axd, and can break some third party components, so use this with caution.

For information on Webresource compression, refer to Miron Abramson's New & Shiny WebResource.axd compression Module.

BlogEngine.Net

BlogEngine.Net is a wonderful blogging platform (it's used for this site) and it has a lot of example code for these techniques listed here.  For more information, refer to the BlogEngine.core modules image.axd, css.axd, and js.axd.

Sample code from BlogEngine.Net CSS Handler


private static void SetHeaders(int hash, HttpContext context)
{ 
   context.Response.ContentType = "text/css";
   context.Response.Cache.VaryByHeaders["Accept-Encoding"] = true;
 
   context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(7));
   context.Response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
   context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
 
   string etag = "\"" + hash.ToString() + "\"";
   string incomingEtag = context.Request.Headers["If-None-Match"];
 
   context.Response.Cache.SetETag(etag);
 
   if (String.Compare(incomingEtag, etag) == 0)
   {
       context.Response.Clear();
       context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotModified;
       context.Response.SuppressContent = true;
   }
}

Recommendations

  1. Minimize the number of HTTP requests by minimizing the unique content that must be loaded on a page.
  2. Set an expiration time to enable the cache to eliminate HTTP requests that would involve 304 responses. 30+ days for images, 1+ days for CSS and JavaScript files.
  3. Use Compression for page output, CSS and JS.
  4. Do not use compression for images (the algorithms for JPG, PNG already compress data for the image).

Search Terms

  • ASP.net enable content expiration
  • ASP.net expires header
  • ASP.net 304 set expires time images
  • ASP.net httphandler verb css
  • HttpCacheability.Public

References

I've listed the articles that I found appropriate in my research on this topic.

Related Items