Cache Control

gommmmmm edited this page Sep 13, 2010 · 15 revisions

Controlling caches

To keep performance of your web server, it is efficient to set far future date to Expires header. It reduces the number of HTTP requests sent to web server. To accomplish this correctly, you need a way to change filenames when it is modified, to avoid invalid caches to be used, that are already deprecated but not yet expired.

SmallCage provides a mechanism to modify filenames and to maintain the references to such files. This allows you to update your site without being annoyed by invalid caches.

Limitation

Currently, SmallCage uses revision numbers provided by Subversion to make filenames specific to its status. Files of the name with --latest, or smc source files of them, must be committed to Subversion repository.

Ability to handle version numbers by other means might be implemented in future version of SmallCage.

1. Change filename

At first, change name of the files you want them to be handled by this mechanism. Add --latest to filename, for example, foo.js should be renamed to foo--latest.js.

2. Change links

On HTML or CSS, the references to the files renamed at step 1 also need be changed. Simply use the new filename as replacement. For example, src="foo.js" should be rewritten to src="foo--latest.js".

Your site still works fine because no replacement by the mechanism occurs at this point. You can publish and view pages just the same as before.

3. Import libraries

Invoke smc import cache and libraries used for cache control will be expanded in /_smc directory.

/_smc/filters
/_smc/filters/cache_filter.rb
/_smc/filters/filters.yml
/_smc/rakelib/cache.rake

4. Automatic replacement of filenames and references

On deployment to an environment which uses far-future Expires header, invoke cache:update rake task instead of usual smc update. This rake task do two manipulation on your file tree.

  • Makes copy of files which have name with --latest. Revision number is used for a part of new filename.
    • ex) foo--latest.js will be copied to foo-123.js
  • Calls smc update. CacheFilter scans smc files for references to --latest files and replace it with the versioned filename.
    • ex) src="foo--latest.js" will be replaced to src="foo-123.js"

After execution, copy of --latest files are referenced with newly created filename, which have never been cached by any client. Following step 4 on every modification to you site, copies of --latest files will be created with the newest revision number, thus you can avoid undesirable cache problems.

Note: If Rakefile is placed under _smc directory (default), move to _smc dir by cd _smc before execution, or specify Rakefile by -f option like rake -f _smc/Rakefile cache:update.

5. Old files to be removed

When the files are modified (and committed), revision number goes up. After next execution of cache:update task, copies created at step 4 got to have no reference. To delete dereferenced files, execute cache:delete_old rake task; cache:update does not perform any deletion, since deleting them may cause broken link on pages not yet republished.

To delete all files created for cache control, execute cache:clean rake task.

Target files

Files with these suffixes are recognized as target of cache control.

  • *--latest.css
  • *--latest.js
  • *--latest.png
  • *--latest.jpg
  • *--latest.gif
  • *--latest.ico

Detailed discussion on cache:update task

Sometimes, cache:update task twice performs smc update and copying. Files like default--latest.css.smc, published into default--latest.css, may contain references to other versioned files (ex. logo--latest.png). On first execution of smc update, files to be actually used are not yet created, so replacement of reference can’t be accurate (ex. replacement to logo--latest.png can’t be resolved before logo-123.png has been created). Second time (after copying done), replacement occurs and references will be replaced with correctly versioned filenames (ex. links to logo--latest.png in default-123.css will be replaced with logo-123.png).

  1. If there is a file of name with --latest, do smc update.
  2. Make copy of the file using versioned name.
    • All filenames are fixed at this point.
    • Revision number will be taken from source smc file, if exists.
  3. Execute smc update to replace links.
  4. Make copy of --latest files again.

1 and 4 are occasional – only when there are smc files that will be published into --latest files.

Detailed discussion on CacheFilter

CacheFilter performs replacement of reference. It replaces links to --latest files with versioned filename. If content string matches regexp like:

%r{(["'])(?!https?://)([^"']+--latest\.(?:css|js|png|gif|jpg|ico))(["'])}

then the filter searches for files with versioned filename, find filename with the largest revision number, and replace mathes with it.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.