• Aucun résultat trouvé

Expiry Headers

Dans le document Oracle Application Express (Page 33-38)

In the previous section we covered compressing the web server output. In this section, we will cover the expiry headers features which enabled browsers to cache static content locally rather than requesting it from the web server every time. If we look again at YSlow, you can see in Figure 1-15 that we get graded an F for the Add Expires headers test.

CHAPTER 1  OHS, EPG, AND APEX LISTENER COMPARED

Figure 1-15. Examining expiry headers in YSlow

So what are expiry headers? Well, in a nutshell, when the browser requests a resource, such as an image, from the web server the web server can add a header to the response to tell the browser how long that resource can be cached in the browser’s local cache. If the browser needs that resource again, it can look in the local cache and check if the resource is still valid by looking at the date in the expiry header. If the cached version is still “within date”, the browser can use the cached version, thereby avoiding a web server request; otherwise, the browser will request the resource from the web server again.

Let us look again at the components section and examine the expiry header, as shown in Figure 1-16.

Figure 1-16. No expiry headers set

Notice that currently there are no expiry headers set. There is, however, something called an ETag, which we will discuss shortly. As I mentioned previously, Expiry headers allow us to tell the browser that a particular resource can be cached locally until a particular time. Note that you cannot force the browser to do this, it is completely up to each individual browser whether they cache the resource or not (since the user might have turned caching off, or have a very small cache region), so consider expiry headers a hint/suggestion rather than a rule that the browser must obey.

So how do you configure expiry headers? Well, the configuration is slightly easier than with mod_gzip since the mod_expires Apache module is shipping out of the box with the OHS.

First, you need to load the mod_expires module, so add the following line to your httpd.conf if it does not already exist:

LoadModule expires_module modules/mod_expires.so

Next, we need to include the configuration file for the expiry settings:

# Include the mod_expires configuration file

include "/oracle/ohs/Apache/Apache/conf/mod_expires.conf"

As I mentioned in the mod_gzip section, I prefer to maintain a separate configuration file for these things, rather than cluttering up the main httpd.conf file. So you will need to create this file and adjust the path to suit your own environment.

Now let us take a look at a sample mod_expires.conf file; note that this is a simple example and you can change the values to suit your own needs:

ExpiresActive On

ExpiresByType image/gif "access plus 15 days"

ExpiresByType image/jpeg "access plus 15 days"

ExpiresByType image/png "access plus 15 days"

ExpiresByType application/x-javascript "access plus 7 days"

ExpiresByType text/javascript "access plus 7 days"

CHAPTER 1  OHS, EPG, AND APEX LISTENER COMPARED

ExpiresByType text/css "access plus 7 days"

FileETag None

The directives for the mod_expires module are quite logical (and well documented); it is fairly easy to understand what they mean even if you have never seen mod_expires rules before. In this case, I first enable the mod_expires module with this line:

ExpiresActive On

Next, we define the rules for the different content types, based on their mime type. For example:

ExpiresByType image/gif "access plus 15 days"

means that all GIF images will have an expiry header added with a date to expire 15 days from the date they were just accessed. In other words, if the browser needs that GIF image again and it is within 15 days from the time it was last requested from the web server, then the browser will be able to use the cached local version. The rest of the rules follow a similar pattern. In the case of Javascript and CSS files, we define shorter cache durations since we expect those files to be changed more frequently. The final line

FileETag None

disables ETags. So what are ETags? Well, ETags (Entity Tags) are a way for the browser and web server to determine if a resource has changed. So, for example, if the browser needs to load the logo for your web page, it can contact the web server and ask if the resource is different to the cached version that the browser already has. If the resource is different (in other words, if it has changed), the web server will send the browser the updated version. If the resource has not changed, the web browser can use the cached version, thereby saving the overhead of downloading the new version. The way the browser and server determine whether the resource has changed or not is via the ETag, which is essentially a unique identifier based on attributes of the resource (perhaps the last updated date, or the file size, or a combination). You don’t need to worry too much about how ETags work since the server is responsible for generating the ETag identifiers transparently if you have them enabled.

So how do ETags compare to Expiry Headers, and would you benefit from them? Well, they certainly can help in some situations and at first glance might appear to perform the same functionality as Expiry Headers. However, there is a very subtle difference, namely:

• When you use ETags, the browser still always contacts the web server to verify if the resource has been modified.

• When you use expiry headers (and no ETags), the browser will only contact the web server if it does not have the resource in the local cache or the expiry date has passed.

Whenever I present on this topic, I have a little example which I think helps to illustrate the subtleties, so please bear with me while I describe it. If you think about the different options regarding expiry headers and browser caching, it’s a bit like making a cup of coffee (I told you,bear with me!):.

No caching: I get up in the morning, look in the fridge and find I have no milk so I go to the store, buy some milk, and come back home and make my coffee. Every time I want to make coffee I go back to the store to buy fresh milk.

Expiry headers only: I look in the fridge, see that I have no milk, so I go to the store to buy some milk, come home and make my coffee. The next time I want to make coffee I look in the fridge and, if the milk is still within date, I can use it; otherwise, I have to go back to the store to buy fresh milk.

ETags: I look in the fridge, see that I have no milk, go to the store and buy some milk, come home and make my coffee. The next time I want to make coffee, I take the milk out of the fridge and take it to the store with me. I then have the following conversation: “Hey, I have some milk here that still looks okay to me, but do you have any fresher milk?”I If the store keeper does have fresher milk, I take that back home with me. If they don’t, I go all the way back home and use the same milk I already had.

Hopefully that very silly story helps to make the differences between the methods more concrete.

And while this might make it sound like I am not a big fan of ETags, that is not true; I think they certainly have their uses. However, with a system such as APEX, where each web server request might result in a database request (if that resource is stored in the database), you need to be very careful that you don’t make unnecessary requests if you hope to scale to large volumes of users.

Okay, now we have enabled Expiry Headers, what difference has that made? If we rerun Yslow, we should see that we score an A for the Add Expires headers test, as shown in Figure 1-17.

Figure 1-17. Running YSlow with Expiry Headers enabled

CHAPTER 1  OHS, EPG, AND APEX LISTENER COMPARED

If we drill down into the detail of the components, you should see that each of the resource types that we specified in the mod_expires.conf file should now have an expiry header attached to it, as shown in Figure 1-18.

Figure 1-18. Expiry headers defined

Dans le document Oracle Application Express (Page 33-38)