Hardware and software setup

Prohibition of page caching on HTML, PHP, htaccess. How to remove caching of css and js files Disable css caching

The cache plays an important role in the operation of almost any web application at the level of working with databases, web servers, and also on the client.

In this article, we will try to deal with client-side caching. In particular, let's look at what http headers are used by browsers and web servers and what they mean.

But first, let's find out why do you need client-side caching at all?.

Web pages consist of many different elements: pictures, css and js files, etc. Some of these elements are used on several (many) pages of the site. Client-side caching is the ability of browsers to keep copies of files (server responses) so as not to re-download them. This allows you to significantly speed up the reloading of pages, save on traffic, and also reduce the load on the server.

There are several different HTTP headers to control client-side caching. Let's talk about each of them.

Http headers to control client side caching

First, let's see how the server and browser interact in the absence of any caching. For a visual understanding, I tried to imagine and visualize the process of communication between them in the form of a text chat. Imagine for a few minutes that the server and the browser are people who correspond with each other :)

Without cache (in the absence of caching http headers)

As we can see, each time the cat.png image is displayed, the browser will download it from the server again. I don't think I need to explain that it's slow and inefficient.

The response header is Last-modified and the request header is if-Modified-Since .

The idea is that the server adds a Last-modified header to the file (response) it gives to the browser.

The browser now knows that the file was created (or modified) on December 1, 2014. The next time the browser needs the same file, it will send a request with an if-Modified-Since header.

If the file has not been modified, the server sends an empty response to the browser with a 304 (Not Modified) status. In this case, the browser knows that the file has not been updated and can display the copy it saved last time.

Thus, using Last-modified we save on loading big file, getting off with an empty quick response from the server.

Etag response header and If-None-Match request header.

The principle of operation of Etag is very similar to Last-modified , but, unlike it, is not tied to time. Time is a relative thing.

The idea is that on creation and every change, the server marks the file with a special tag called ETag , and also adds a header to the file (response) that it gives to the browser:

ETag: "686897696a7c876b7e"

Now the browser knows that the file current version has an ETag equal to “686897696a7c876b7e”. The next time the browser needs the same file, it will send a request with an If-None-Match: "686897696a7c876b7e" header.

If-None-Match: "686897696a7c876b7e"

The server can compare the labels and, if the file has not been modified, send an empty response to the browser with a 304 (Not Modified) status. As with Last-modified, the browser will figure out that the file has not been updated and will be able to display the cached copy.

Header Expired

The way this header works is different from the above Etag and Last-modified . With the help of Expired, the “expiration date” (“relevance date”) of the file is determined. Those. on first load, the server lets the browser know that it doesn't plan to modify the file before the date specified in Expired:

The next time the browser, knowing that the "expiration date" has not yet arrived, will not even try to make a request to the server and will display the file from the cache.

This type of cache is especially relevant for illustrations for articles, icons, favicons, some css and js files, etc.

Cache-control header with max-age directive.

How Cache-control: max-age works is very similar to Expired . The “expiration date” of the file is also determined here, but it is set in seconds and is not tied to a specific time, which is much more convenient in most cases.

For reference:

  • 1 day = 86400 seconds
  • 1 week = 604800 seconds
  • 1 month = 2629000 seconds
  • 1 year = 31536000 seconds

For instance:

Cache-Control: max-age=2629000;

The Cache-control header has other directives besides max-age . Let's take a quick look at the most popular:

public
The fact is that not only the end client of the user (browser) can cache requests, but also various intermediate proxies, CDN networks, etc. So, the public directive allows absolutely any proxy server to perform caching on a par with the browser.

private
The directive says that given file(server response) is end user specific and should not be cached by different intermediate proxies. However, it allows caching to the end client (the user's browser). For example, this is relevant for internal pages user profile, requests within a session, etc.

Allows you to specify that the client should make a request to the server each time. Sometimes used with the Etag header described above.

no store
Indicates to the client that it should not keep a copy of the request or parts of the request under any circumstances. This is the strictest header, overriding any caches. It was designed specifically to work with confidential information.

must-revalidate
This directive tells the browser to make a mandatory request to the server to re-validate the content (for example, if you are using eTag). The fact is that http in a certain configuration allows the cache to store content that is already out of date. must-revalidate obliges the browser, under any conditions, to check the freshness of the content by requesting the server.

proxy-revalidate
This is the same as must-revalidate , but only applies to caching proxies.

s-maxage
Almost identical to max-age , except that this directive is only respected by the various proxy caches, not by the user's browser itself. Letter " s-” comes from the word “ s shared" (for example, CDN). This directive is specifically for CDNs and other intermediary caches. Specifying it overrides the max-age directive and the Expired header. However, if you are not building CDN networks, then you are unlikely to ever need s-maxage.

How to see what headings are used on the site?

You can view the http request headers and response headers in your favorite browser's debugger. Here is an example of how it looks in chrome:

The same thing can be seen in any self-respecting browser or http sniffer.

Setting up caching in Apache and Nginx

We will not retell the documentation for setting up popular servers. You can always watch it and. Below we will give some real-life examples to show what the configuration files look like.

Apache configuration example for Expires control

We set a different “expiration date” for different types of files. One year for images, one month for scripts, styles, pdfs and icons. For everything else - 2 days.

ExpiresActive On ExpiresByType image/jpg "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType text/css "access plus 1 month" ExpiresByType application/pdf "access plus 1 month" ExpiresByType text/x-javascript "access plus 1 month" ExpiresByType image/x-icon "access plus 1 year" ExpiresDefault "access plus 2 days"

Example Nginx Configuration to Control Expires

We set a different “expiration date” for different types of files. One week for images, one day for styles and scripts.

Server ( #... location ~* \.(gif|ico|jpe?g|png)(\?+)?$ ( expires 1w; ) location ~* \.(css|js)$ ( expires 1d; ) #... )

Apache configuration example for Cache-control (max-age and public/private/no-cache)

Header set Cache-Control "max-age=2592000, public" Header set Cache-Control "max-age=88000, private, must-revalidate" Header set Cache-Control "private, no-store, no-cache, must-revalidate, no-transform, max-age=0" Header set Pragma "no-cache"

Nginx configuration example for Cache-control static files

server ( #... location ~* \.(?:ico|css|js|gif|jpe?g|png)$ ( add_header Cache-Control "max-age=88000, public"; ) #... )

Finally

“Cache everything that can be cached” is a good motto for a web developer. Sometimes you can spend just a few hours on configuration and still significantly improve the user experience of your site, significantly reduce server load and save on traffic. The main thing is not to overdo it and set everything up correctly, taking into account the characteristics of your resource.

  • htaccess caching saves the content of a web page to local computer when the user visits it;
  • Browser cache usage - The webmaster instructs browsers on how to view resources.

When a browser renders a web page, it must load the logo, CSS file, and other resources:

The browser cache "remembers" the resources that the browser has already downloaded. When a visitor goes to another page of the site, the logo, CSS files, etc. should not be downloaded again because the browser has already "remembered" them (saved ). This is the reason why a web page takes longer to load on the first visit than on repeated visits.

When you use caching, the web page files will be stored in the browser's cache. Pages will load many times faster on repeated visits. It will also be with other pages that use the same resources.

How to enable caching in the browser

  • Change resource request headers to use caching;
  • Optimize your caching strategy.

Changing request headers

For most people, the only way to cache an htaccess site is to add code to the .htaccess file on the web server.

The .htaccess file controls many important settings for your site.

Browser caching via .htaccess file

The code below tells the browser what to cache and how long to "remember". It should be added to the top of the .htaccess file:

## EXPIRES CACHING ## ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType text/css "access 1 month" ExpiresByType text/ html "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType text/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 1 month"## EXPIRES CACHING ##

Save the .htaccess file and then refresh the web page.

How to set cache times for different file types

In the code above, the time spans are set. For example, 1 year (1 year) or 1 month (1 month). They are associated with file types. The code above states that .jpg files (images) should be cached for a year.

If you wanted to change this so that JPG images are also cached for a month, then you would simply replace "1 year" with "1 month". The above htaccess caching values ​​are optimal for most web pages.

Alternate caching method for .htaccess

The above method is called " Expires“, it helps with caching for most beginners. Once you get comfortable with caching, you can try another caching method, Cache-Control , which gives you more options.

It's possible that the Expires method won't work on your server, in which case you might want to try using Cache-Control .

Cache-Control

This method allows you to have more control over the browser's page caching, but many people find it easier to write all the settings once.

Usage example in .htaccess file:

#1 month for most static assets Header set Cache-Control "max-age=2592000, public"

The above code sets the Cache-Control header depending on the file type.

How Cache Control Works

Consider the above line of browser caching code in htaccess :

#1 Month for most static assets

This line is just a note. The .htaccess file ignores lines that start with # . This note is recommended as you may have multiple different sets data as a file caching solution:

The line mentioned above says that, " if the file is one of these types, then we will do something with it...»

The most important thing about this line is that it lists different types files ( css, JS, JPEG, PNG etc. ) and that caching instructions should be applied to these file types. For example, if you don't want JPG files to be cached for a specified period of time, you can remove " JPG". If you want to add HTML , then you need to specify in this line " HTML«:

Header set Cache-Control "max-age=2592000, public"

The line mentioned above has the actual headers and values ​​set:

  • Part " Header set Cache-Control» - sets the title;
  • Variable " max-age=2592000' - indicates how long the caching process will take (in seconds). In this case, we are caching for one month (2592000 ) seconds;
  • Part " public' indicates that it is public.

This caching line via htaccess closes the statement and ends the block of code.

General caching problem

If you are listing images that will be cached for a year or more, remember that if you make changes to your pages, they may not be visible to all users. Since users will refer to cached files, and not to existing ones. If there is a file that you edit periodically ( for example - CSS file), you can overcome the cache problem by using URL fingerprinting.

URL fingerprint

Getting a new (non-cached) file resource is possible if there is a unique name. For example, if the CSS file is named "main.css", then we could name it "main_1.css" instead. The next time we change its name, we can name the file "main_2.css". This is useful for files that change periodically.

HTML5 made it possible to create web applications that will work even without an internet connection.

Improved page caching

Note: IE10+, Chrome, Firefox, Opera and Safari support this technology.

HTML5 expands the capabilities of browser caching. Now web pages can be fully accessible to users even without an internet connection.

Using HTML5 caching provides the following benefits:

  • The ability to view web pages by users even without an Internet connection.
  • Increase page loading speed - pages are stored locally on the user's computer and will therefore load much faster.
  • Reducing the load on the server - the server will not have to process some of the user requests.

An example of using HTML5 caching

...Document content...

Declaring HTML5 caching

In order to use the caching mechanism on your web pages, you need to add to the tag manifest attribute and set its value to the path to special file, which declares caching options.

If this attribute has not been set on the web page and the link to it is not in the cache file, the page will not be cached.

The cache file can have any extension (such as .appcache or .mf), but must have a special MIME type: "text/cache-manifest".

In some cases, the web server may need to additional setting to serve the given MIME type. For example, to set up the Apache web server you need to add the following code to your .htaccess file:

AddType text/cache-manifest .appcache

Contents of the cache file

The cache file is normal text file, which tells the browser which files to cache.

The file can contain three sections:

  • CACHE MANIFEST - this section contains links to files that need to be cached. The browser will automatically cache all the listed files right after the first download.
  • NETWORK - this section specifies the files that require permanent connection to the internet. The browser will not cache the files listed in this section.
  • FALLBACK - if the files specified in this section are inaccessible for any reason, users will be automatically redirected to another specified file.

The CACHE MANIFEST section must be present in all cache files. The NETWORK and FALLBACK sections may be missing.

Example cache file:

CACHE MANIFEST #This section lists the files that will be cached index.html flower.png NETWORK #This lists the files that require an internet connection login-page.php FALLBACK #If mob.html is not available, the user will be redirected to offline.html /mob .html /offline.html #If any of the HTML files is not available, the user will be redirected to offline.html *.html /offline.html

Note: the web page that links to the cache file will be automatically cached, so including it in the cache file itself is optional, but recommended nonetheless.

Note: some browsers may have a limit on the size of cached content on a single site.

Update Cached Files

Once the files are cached, the browser will continue to show their cached version over and over again even if you change the content of those files on the server.

To update cached content you must do one of the following:

  • Clear the cache in the user's browser
  • Update the content of the cache file
  • Refresh browser cache programmatically (using JavaScript)

In order to update the content of a file, you can use the following trick: instead of updating the content of the file directly, you can add a comment to it with the modification date and/or file version, and in the future only change the content of that comment whenever you want. update cached content.

Sometimes, it may be necessary to prevent the browser from caching a page, since the information on it is updated every time. This can be data generation, according to the selected filters, or other content that is created in a new way each time. In short, there are times when you need to prevent a malicious program from caching a page. Today, we will learn how to implement it different ways, using PHP or HTML or .htaccess.

Disable page caching in HTML

You can do this using meta tags. Now we will analyze different options for banning caching.

Prohibit caching by the browser and proxy server

Disable page caching, browser only

Setting caching to certain time, for browser

With the code below, we can tell the browser how long to keep the document in the cache. After that, the cache will be updated.

Setting caching for a specific time, for a proxy server

Practically, the same as in the previous code, only the indication is specifically for the proxy server.

Prevent page caching with PHP

Practically, everything is the same as in the case of HTML, only we will output information through the header headers. Here's how to implement an absolute no-cache:

", date("H:i:s"), ""; ?>

Also, you can allow caching for a certain time. For example, let's allow caching for only 1 hour.

", date("H:i:s"), ""; ?>

Prevent page caching with .htaccess

For ease of implementation of the idea, everything can be done at the configuration level Apache server. Before that, we need to make sure that the required modules are in working order. We open configuration file Apache and observe the following picture:

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

Now in the .htaccess file, we actually prohibit caching the output data. As we know, the .htaccess file will be distributed to the directory in which it is located, and to all subdirectories.

# Cache-Control header Header append Cache-Control "no-store, no-cache, must-revalidate"# Expires header ExpiresActive On ExpiresDefault "now"

It is important to note that a complete ban on caching increases the load on the server. So play with it carefully! Better yet, set a specific time for which documents can be cached. For example, let's set caching for 1 hour:

# Cache-Control header Header append Cache-Control "public"# Expires header ExpiresActive On ExpiresDefault "access plus 1 hours"

Conclusion

By including external CSS and Javascript, we want to keep unnecessary HTTP requests to a minimum.

To do this, .js and .css files are given with headers that provide reliable caching.

But what to do when one of these files changes during development? All users in the cache have the old version - until the cache is outdated, there will be a lot of complaints about the broken integration of the server and client parts.

The correct way of caching and versioning completely eliminates this problem and provides reliable, transparent synchronization of style / script versions.

Simple ETag caching

The easiest way to cache static resources is to use ETag .

It is enough to enable the appropriate server setting (it is enabled by default for Apache) - and each file will be given an ETag in the headers - a hash that depends on the update time, file size and (on the inode-based file systems) inode.

The browser caches such a file and on subsequent requests specifies the If-None-Match header with the ETag of the cached document. Having received such a header, the server can respond with a 304 code - and then the document will be taken from the cache.

It looks like this:

First request to the server (cache clear) GET /misc/pack.js HTTP/1.1 Host: site

In general, the browser usually adds a bunch of headers like User-Agent, Accept, and so on. For brevity, they are cut.

Server response The server sends back a document with a 200 code and ETag: HTTP/1.x 200 OK Content-Encoding: gzip Content-Type: text/javascript; charset=utf-8 Etag: "3272221997" Accept-Ranges: bytes Content-Length: 23321 Date: Fri, 02 May 2008 17:22:46 GMT Server: lighttpd Next Browser Request On the next request, the browser adds If-None-Match: (cached ETag): GET /misc/pack.js HTTP/1.1 Host: site If-None-Match: "453700005" Server response The server is looking - yep, the document hasn't changed. So you can issue a 304 code and not send the document again. HTTP/1.x 304 Not Modified Content-Encoding: gzip Etag: "453700005" Content-Type: text/javascript; charset=utf-8 Accept-Ranges: bytes Date: Tue, 15 Apr 2008 10:17:11 GMT

Alternatively, if the document has changed, then the server simply sends 200 with the new ETag .

The Last-Modified + If-Modified-Since bundle works in a similar way:

  1. server sends last modification date in Last-Modified header (instead of ETag)
  2. the browser caches the document, and on the next request for the same document sends the date of the cached version in the If-Modified-Since header (instead of If-None-Match)
  3. the server checks the dates, and if the document has not changed, it sends only a 304 code, without content.

These methods work stably and well, but the browser still has to do on demand for each script or style.

Smart caching. Versioning

The general approach for versioning - in a nutshell:

  1. The version (or modification date) is added to all scripts. For example, http://website/ my.js will become http://website/ my.v1.2.js
  2. All scripts are hard cached by the browser
  3. When updating the script, the version changes to a new one: http://website/ my.v2.0.js
  4. The address has changed, so the browser will request and cache the file again
  5. The old version 1.2 will gradually fall out of the cache

Hard caching

Hard caching- a kind of sledgehammer that completely nails requests to the server for cached documents.

To do this, just add the Expires and Cache-Control: max-age headers.

For example, to cache for 365 days in PHP:

Header("Expires: ".gmdate("D, d M Y H:i:s", time()+86400*365)." GMT"); header("Cache-Control: max-age="+86400*365);

Or you can cache content permanently using mod_header in Apache:

Having received such headers, the browser will hard cache the document for a long time. All further accesses to the document will be directly served from the browser cache, without a call to the server.

Most browsers (Opera, Internet Explorer 6+, Safari) DO NOT cache documents if the address contains question mark, because they are considered dynamic.

That's why we add the version to the filename. Of course, with such addresses, you have to use a solution like mod_rewrite, we will consider this later in the article.

P.S But Firefox caches addresses with question marks..

Automatic name resolution

Let's see how to automatically and transparently change versions without renaming the files themselves.

Name with Version -> File

The simplest is to turn the versioned name into the original filename.

At the Apache level, this can be done with mod_rewrite :

RewriteEngine on RewriteRule ^/(.*\.)v+\.(css|js|gif|png|jpg)$ /$1$2 [L]

Such a rule processes all css/js/gif/png/jpg files, stripping the version from the name.

For example:

/images/logo.v2.gif -> /images/logo.gif
/css/style.v1.27.css -> /css/style.css
/javascript/script.v6.js -> /javascript/script.js

But besides cutting out the version, you also need to add hard caching headers to files. For this, the mod_header directives are used:

Header add "Expires" "Mon, 28 Jul 2014 23:30:00 GMT" Header add "Cache-Control" "max-age=315360000"

And all together it implements the following Apache config:

RewriteEngine on # removes the version, and at the same time sets the variable that the file is versioned RewriteRule ^/(.*\.)v+\.(css|js|gif|png|jpg)$ /$1$2 # hard cache versioned files Header add "Expires" "Mon, 28 Jul 2014 23:30:00 GMT" env=VERSIONED_FILE Header add "Cache-Control" "max-age=315360000" env=VERSIONED_FILE

Due to the way the mod_rewrite module works, RewriteRule must be placed in the main httpd.conf configuration file or in files included with it, but in no case in .htaccess , otherwise the Header commands will be run first, before being set variable VERSIONED_FILE .

Header directives can be anywhere, even in .htaccess - it doesn't matter.

Automatically add version to filename in HTML page

How to put the version in the script name depends on your template system and, in general, the way you add scripts (styles, etc.).

For example, when using the modification date as the version and the Smarty template engine, links can be set like this:

The version function adds a version:

Function smarty_version($args)( $stat = stat($GLOBALS["config"]["site_root"].$args["src"]); $version = $stat["mtime"]; echo preg_replace("! \.(+?)$!", ".v$version.\$1", $args["src"]); )

Result on the page:

Optimization

To avoid unnecessary calls to stat , you can store an array with a list of current versions in a separate variable

$versions["css"] = array("group.css" => "1.1", "other.css" => "3.0", )

In this case, the current version from the array is simply substituted into the HTML.

You can cross both approaches, and issue during development a version by modification date - for relevance, and in production - a version from an array, for performance.

Applicability

This kind of caching works everywhere, including Javascript, CSS, images, flash movies, and so on.

It is useful whenever the document changes, but the browser should always have the current up-to-date version.

Liked the article? Share with friends!
Was this article helpful?
Yes
Not
Thanks for your feedback!
Something went wrong and your vote was not counted.
Thanks. Your message has been sent
Did you find an error in the text?
Select it, click Ctrl+Enter and we'll fix it!