how to cache css, images and js?
Asked Answered
F

6

26

I would like to have images, css, and javascript cached client-side on their browser when they load up a web page. There are so many different types of caching I am confused as to which ones to use with asp.net mvc.

Would it also be possible to have their browsers check for new or modified versions of these files?

Thanks!

Fourier answered 20/1, 2010 at 22:23 Comment(0)
Q
6

Browsers take care of this for you automatically, actually. You have to go out of your way to get them to NOT cache css, js, html and images.

I'm not that familiar with ASP MVC, but I think they type of caching you're thinking of is opcode caching for your created dynamic output server-side?

Quarterphase answered 20/1, 2010 at 22:25 Comment(2)
Things are not really that simple. Caching is important if you care about a bug-free and well performing site. You want to avoid visitors having to re-download content, but you also want to avoid visitors having out-of-date content. In ASP.NET MVC I use an approach that includes an MD5 hash in the URL which achieves this without too much thought after it's set up. Check out my answer here for source code.Graze
@Drew Sure, this wasn't intended to be an overview of caching. Just telling the asker that if you don't need finer grained control, existing defaults in browsers and servers are not so bad. Apache is usually configured to serve ETags, etc. and browsers usually go along with 304s. Checked out your solution, and that is a good idea! I am likely to use that idea in Django soon.Quarterphase
M
47

You need to set cache control headers on the server. You can do this by sticking this in your web.config:

<system.webServer>
  <staticContent>
     <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
  </staticContent>
</system.webServer>

This would tell the browser now to even check for new content on anything static for 30 days.

For your second question, provide some mechanism of adding a querystring to the content. In my current project we compress and combine and javascript and css as part of the build. When putting links in the page is looks like:

<script src="/Resources/Javascript/Combined.js?v=2.2.0.1901" type="text/javascript"></script>

The querystring is the Major.Minor.0.Changeset number and changes anytime we push a build, causing the client to re-fetch it. The same exact thing happens on stylesheets in their <link> element.

Machzor answered 20/1, 2010 at 22:32 Comment(9)
Would that clientcache also cache the html? I would like to speed up my account areas that make heavy use of ajax by caching just the scripts, css, and images (not the html). What would you recommend for this?Fourier
@chobo: This would only affect static content...this is a direction to IIS 7 on how to handle things ASP.Net doesn't (images, css, js). Anything dynamic like an aspx does NOT get this header and wouldn't be cached.Machzor
Using query strings for versions means that some proxy servers won't cache the file. Better off putting it in the URL directly. And if you're going to do that, use an MD5 hash of the file content and swap the concept of versioning for the concept of identity. I have some source code here that shows how I do it at the moment. Would appreciate thoughts and feedback.Graze
@Drew - yup, that's what the we do here at Stack Exchange - except we stick with the query string. If you're behind a proxy that doesn't respect that different query strings are different content...you have much larger issues.Machzor
So setting cacheControlMaxAge to say: -1.00:00:00 would make the browser not to cache js, css and images? all resources? I'd need not to cache anything.Histogram
I believe the System.web.optimization bundle stuff for mvc now a days takes care of the query string part of this automatically by appending some sort of ?v=hashe string to the bundle name.Lanham
@DylanHayes true...but only if you're using the bundle stuff, we don't use that here since there are other compile-time concerns such as localization.Machzor
@Nick understandable, just adding to the comments so people know.Lanham
It's the best answer! That worked very well for me. But I'm still getting a warning on google audit about "uses inefficient cache policy". Even giving 30 days cache.Sciolism
Q
6

Browsers take care of this for you automatically, actually. You have to go out of your way to get them to NOT cache css, js, html and images.

I'm not that familiar with ASP MVC, but I think they type of caching you're thinking of is opcode caching for your created dynamic output server-side?

Quarterphase answered 20/1, 2010 at 22:25 Comment(2)
Things are not really that simple. Caching is important if you care about a bug-free and well performing site. You want to avoid visitors having to re-download content, but you also want to avoid visitors having out-of-date content. In ASP.NET MVC I use an approach that includes an MD5 hash in the URL which achieves this without too much thought after it's set up. Check out my answer here for source code.Graze
@Drew Sure, this wasn't intended to be an overview of caching. Just telling the asker that if you don't need finer grained control, existing defaults in browsers and servers are not so bad. Apache is usually configured to serve ETags, etc. and browsers usually go along with 304s. Checked out your solution, and that is a good idea! I am likely to use that idea in Django soon.Quarterphase
N
4

@Paul Creasey and @Salsa are both correct that browsers will handle caching by default so long as the link is the same.

As you mentioned, this raises a problem when you need to update those files as you have no guarantee that the client's browser will check for an updated version. In many cases they only do this after a fixed amount of time has passed which can create a crummy user experience.

There are a number of questions already asked on this site as to how to handle alerting the client browsers to refresh the cache. In short, they all rely on changing the link when you change the file's contents.

You can append a parameter to the URL that will only be used for caching purposes such as:

<script src="/myJavascript.js?version=4"></script>

Then just change the version number when you change the contents and need to force a client side refresh ala this answer.

Numerate answered 20/1, 2010 at 22:32 Comment(0)
G
2

Take a look at the answer I posted here for a solution that maximises the benefit of using caching, and avoids any problems with needing users to 'hard' refresh (Ctrl+F5).

It uses an MD5 hash of the content itself in the URL, so that the URL remains the same as long as the file is the same, which is really the goal. Calculating the hash is super fast, and it's cached in memory on the server so page rendering isn't noticeably slowed down. The whole thing is measured in microseconds, and the benefits have been (on my site for scuba divers) awesome so far. I apply it to all images, CSS and JS with the exception of images from within CSS files as they're not server-generated on my site (yet.)

Graze answered 22/6, 2011 at 15:24 Comment(0)
C
0

This is best done in IIS or in your config file - make sure your CSS/JS/images are set to never expire.

When you reference them from your code, I suggest appending a version or build-date to the filename, e.g. script.js?20100120, so that when you do come around to changing them, you just need to change the version to force a refresh from all the browsers that have cached it.

Cardamom answered 20/1, 2010 at 22:33 Comment(0)
A
-2

Client side caching is handled automatically by browsers when you properly set Cache-Control headers and set web.config. Like that :

<system.webServer>
    <staticContent>
        <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00.00:10:00" />
    </staticContent>
</system.webServer>
Adversative answered 20/1, 2010 at 22:26 Comment(1)
It's not that simple really. You must provide the appropriate headers in the HTTP response. Furthermore, you need to tell browsers to invalidate their cache somehow when your content changes, otherwise the site fails until they do a hard refresh.Graze

© 2022 - 2024 — McMap. All rights reserved.