How To Optimize Your Site With HTTP Caching

来源:互联网 发布:c语言大全 app 编辑:程序博客网 时间:2024/05/17 03:10

[转载] http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/

 

 

I’ve been on a web tweaking kick lately: how to speed up your javascript, gzip files with your server, and now how to set up caching. But the reason is simple: site performance is a feature.

For web sites, speed may be feature #1. Users hate waiting,we get frustrated by buffering videos and pages that pop together asimages slowly load. It’s a jarring (aka bad) user experience. Timeinvested in site optimization is well worth it, so let’s dive in.


What is Caching?

Caching is a great example of the ubiquitous time-space tradeoff in programming. You can save time by using space to store results.

In the case of websites, the browser can save a copy of images,stylesheets, javascript or the entire page. The next time the userneeds that resource (such as a script or logo that appears on everypage), the browser doesn’t have to download it again. Fewer downloads means a faster, happier site.

Here’s a quick refresher on how a web browser gets a page from the server:

HTTP_request.png

1. Browser: Yo! You got index.html?
2. Server: (Looking it up…)
3. Sever: Totally, dude! It’s right here!
4. Browser: That’s rad, I’m downloading it now and showing the user.

(The actual HTTP protocol may have minor differences; see Live HTTP Headers for more details.)


Caching’s Ugly Secret: It Gets Stale

Caching seems fun and easy. The browser saves a copy of a file (likea logo image) and uses this cached (saved) copy on each page that needsthe logo. This avoids having to download the image ever again and isperfect, right?

Wrongo. What happens when the company logo changes? Amazon.com becomes Nile.com? Google becomes Quadrillion?

We’ve got a problem. The shiny new logo needs to go with the shiny new site, caches be damned.

So even though the browser has the logo, it doesn’t know whether theimage can be used. After all, the file may have changed on the serverand there could be an updated version.

So why bother caching if we can’t be sure if the file is good? Luckily, there’s a few ways to fix this problem.


Caching Method 1: Last-Modified

One fix is for the server to tell the browser what version of the file it is sending. A server can return a Last-modified date along with the file (let’s call it logo.png), like this:

Last-modified: Fri, 16 Mar 2007 04:00:25 GMT
File Contents (could be an image, HTML, CSS, Javascript...)

Now the browser knows that the file it got (logo.png) was created onMar 16 2007. The next time the browser needs logo.png, it can do aspecial check with the server:

HTTP-caching-last-modified_1.png

1. Browser: Hey, give me logo.png, but only if it’s been modified since Mar 16, 2007.
2. Server: (Checking the modification date)
3. Server: Hey, you’re in luck! It was not modified since that date. You have the latest version.
4. Browser: Great! I’ll show the user the cached version.

Sending the short “Not Modified” message is a lot fasterthan needing to download the file again, especially for giantjavascript or image files. Caching saves the day (err… the bandwidth).


Caching Method 2: ETag

Comparing versions with the modification time generally works, butcould lead to problems. What if the server’s clock was originally wrongand then got fixed? What if daylight savings time comes early and theserver isn’t updated? The caches could be inaccurate.

ETags to the rescue. An ETag is a unique identifier given to everyfile. It’s like a hash or fingerprint: every file gets a uniquefingerprint, and if you change the file (even by one byte), thefingerprint changes as well.

Instead of sending back the modification time, the server can send back the ETag (fingerprint):

ETag: ead145f
File Contents (could be an image, HTML, CSS, Javascript...)

The ETag can be any string which uniquely identifies the file. Thenext time the browser needs logo.png, it can have a conversation likethis:

HTTP_caching_if_none_match.png

1. Browser: Can I get logo.png, if nothing matches tag “ead145f”?
2. Server: (Checking fingerprint on logo.png)
3. Server: You’re in luck! The version here is “ead145f”. It was not modified.
4. Browser: Score! I’ll show the user my cached version.

Just like last-modifed, ETags solve the problem of comparing file versions,except that “if-none-match” is a bit harder to work into a sentencethan “if-modified-since”. But that’s my problem, not yours. ETags workgreat.


Caching Method 3: Expires

Caching a file and checking with the server is nice, except for one thing: we are still checking with the server.It’s like analyzing your milk every time you make cereal to see whetherit’s safe to drink. Sure, it’s better than buying a new gallon eachtime, but it’s not exactly wonderful.

And how do we handle this milk situation? With an expiration date!

If we know when the milk (logo.png) expires, we keep using it untilthat date (and maybe a few days longer, if you’re a college student).As soon as it goes expires, we contact the server for a fresh copy,with a new expiration date. The header looks like this:

Expires: Tue, 20 Mar 2007 04:00:25 GMT
File Contents (could be an image, HTML, CSS, Javascript...)

In the meantime, we avoid even talking to the server if we’re in the expiration period:

HTTP_caching_expires.png

There isn’t a conversation here; the browser has a monologue.

1. Browser: Self, is it before the expiration date of Mar 20, 2007? (Assume it is).
2. Browser: Verily, I will show the user the cached version.

And that’s that. The web server didn’t have to do anything. The user sees the file instantly.


Caching Method 4: Max-Age

Oh, we’re not done yet. Expires is great, but it has to be computed for every date. The max-age header lets us say “This file expires 1 week from today”, which is simpler than setting an explicit date.

Max-Age is measured in seconds. Here’s a few quick second conversions:

  • 1 day in seconds = 86400
  • 1 week in seconds = 604800
  • 1 month in seconds = 2629000
  • 1 year in seconds = 31536000 (effectively infinite on internet time)


Bonus Header: Public and Private

The cache headers never cease. Sometimes a server needs to control when certain resources are cached.

  • Cache-control: public means the cached version can be saved by proxies and other intermediate servers, where everyone can see it.
  • Cache-control: private means the file is different fordifferent users (such as their personal homepage). The user’s privatebrowser can cache it, but not public proxies.
  • Cache-control: no-cache means the file should not be cached. This is useful for things like search results where the URL appears the same but the content may change.

However, be wary that some cache directives only work on newer HTTP 1.1 browsers. If you are doing special caching of authenticated pages then read more about caching.


Ok, I’m Sold: Enable Caching

We’ve seen the following headers that really help our caching:

  • Last-modified:
  • ETag:
  • Expires:
  • Cache-control: max-age=86400

Now let’s put it all together and get Apache to return the right headers. If your resource changes:

  • Daily or more: Use last-modifed or ETag. Apache does this for you automatically!
  • Weekly-monthly: Use max-age for a day or week. Put the .htaccess file in the directory you want to cache:
  • Never changes: Use max-age=31536000 and really far-out expires headers.

How can a file never change? Simple. Put different versions of the file in different directories.

For instacalc, I keep the core files of each build in a uniquedirectory, such as “build490″. When I’m using build490, index.htmlpulls all images, stylesheets, and javascripts from that directory. Ican cache the the files in build490 forever because build490 will never change.

If I have a new version (build491… how creative), index.html willpoint to that folder instead. I’ve created scripts to take care of thisfind/replace housekeeping, though you can use URL rewriting rules as well. I prefer to have the HTML point to the actual file.

Remember that index.html cannot be cached forever,since it changes every now and then to point to new directories. So forthe “loader” file, I’m using the regular Last-Modified cachingstrategy. I think it’s fine to have that small “304 Not Modified”communication with the server — we still avoid sending requests for allthe files in the build490 folder. If you want, monkey around and givethe index.html file a small expiration (say a few hours).


Final Step: Check Your Caching

To see whether your files are cached, do the following:

  • Online: Examine your site in the cacheability query (green means cacheable)
  • In Browser: Use FireBug or Live HTTP Headers to see the HTTP response (304 Not Modified, Cache-Control, etc.). In particular, I’ll load a page and use Live HTTPHeaders to make sure no packets are being sent to load images, logos,and other cached files. If you press ctrl+refresh the browser willforce a reload of all files.

Read more about caching, or the HTTP header fields.Caching doesn’t help with the initial download (that’s what gzip isfor), but it makes the overall site experience much better.

Remember: Creating unique URLs is the simplest way to caching heaven. Have fun streamlining your site!

 

 

原创粉丝点击