DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 11.8 Disabling Content Negotiation

Problem

Content negotiation causes a big reduction in performance.

Solution

Disable content negotiation where it is not needed. If you do require content negotiation, use the type-map handler, rather than the MultiViews option:

Options -MultiViews

AddHandler type-map var

Discussion

If at all possible, disable content negotiation. However, if you must do content negotiation—if, for example, you have a multilingual web site—you should use the type-map handler, rather than the MultiViews method.

When MultiViews is used, Apache needs to get a directory listing each time a request is made. The resource requested is compared to the directory listing to see what variants of that resource might exist. For example, if index.html is requested, the variants index.html.en and index.html.fr might exist to satisfy that request. Each matching variant is compared with the user's preferences, expressed in the various Accept headers passed by the client. This information allows Apache to determine which resource is best suited to the user's needs.

However, this process can be very time-consuming, particularly for large directories or resources with large numbers of variants. By putting the information in a .var file and allowing the type-map handler to be used instead, you eliminate the requirement to get a directory listing, and greatly reduce the amount of work that Apache must do to determine the correct variant to send to the user.

The .var file just needs to contain a listing of the variants of a particular resource and describe their important attributes.

If you have, for example, English, French, and Hebrew variants of the resource index.html, you may express this in a .var file called index.html.var containing information about each of the various variants. This file might look like the following:

URI: index.html.en
Content-language: en
Content-type: text/html

URI: index.html.fr
Content-language: en
Content-type: text/html

URI: index.html.he.iso8859-8
Content-language: he
Content-type: text/html;charset=ISO-8859-8

This file should be placed in the same directory as the variants of this resource, which are called index.html.en, index.html.fr, and index.html.he.iso8859-8.

Note that the Hebrew variant of the document indicates an alternate character set, both in the name of the file itself, and in the Content-type header field.

Enable the .var file by adding a AddHandler directive to your configuration file, as follows:

AddHandler type-map .var

Each of the file extensions used in these filenames should have an associated directive in your configuration file. This is not something that you should have to add—these should appear in your default configuration file. Each of the language indicators will have an associated AddLanguage directive, while the character set indicator will have an AddCharset directive.

In contrast to MultiViews, this technique gets all of its information from this .var file instead of from a directory listing, which is much less efficient.

You can further reduce the performance impact of content negotiation by indicating that negotiated documents can be cached. This is accomplished by the directive:

CacheNegotiatedDocs On

Caching negotiated documents can cause unpleasant results, such as people getting files in a language that they cannot read or in document formats that they don't know how to render.

If possible, you should completely avoid content negotiation in any form, as it will greatly slow down your server no matter which technique you use.

See Also

    [ Team LiB ] Previous Section Next Section