Magnolia 5.4 reached end of life on November 15, 2018. This branch is no longer supported, see End-of-life policy.
Magnolia employs a web cache to store server responses so that future requests for the same content can be served faster. The chief benefit of using cache is a reduction in information load on the network, meaning less bandwidth used, reduced processing and improved responsiveness.
<dependency> <groupId>info.magnolia.cache</groupId> <artifactId>magnolia-cache-core</artifactId> <version>5.4.7</version> </dependency>
Although the Cache module is bundled as a separate module, it is essential to Magnolia and many other modules depend on it. Don't uninstall the Cache module. If necessary, disable caching by adding an enabled
node in Configuration > /server/filters/cache
and set its value to false
.
Node name | Value |
---|---|
server | |
filters | |
cache | |
defaultContentCachingConfigurationName | defaultPageCache |
class | info.magnolia.module.cache.filter.CacheFilter |
enabled | false |
Caching is performed by the Cache filter, which is part of the standard Magnolia filter chain. When a request arrives to the Cache filter, the filter passes it to the browser cache policy.
Cache configurations are defined in /modules/cache/config/contentCaching/
. Within each configuration you can define:
Specific implementations of tasks.
Node name | Value |
---|---|
modules | |
cache | |
config | |
contentCaching | |
defaultPageCache | |
uuid-key-mapping | |
compression | |
cacheFactory |
To select one of the cache configurations, set the defaultContentCachingConfigurationName
parameter in the Cache filter. The chosen configuration is read into a JavaBean using the Node2Bean mechanism, making it dynamically available to your own module code.
Node name | Value |
---|---|
server | |
filters | |
cache | |
defaultContentCachingConfigurationName | defaultPageCache |
class | info.magnolia.module.cache.filter.CacheFilter |
Caching behavior for each configuration is defined with policies.
This policy defines whether the requested content should be cached or not. The decision to cache relies on voters, which are used whenever configuration values are not assigned at startup but depend on rules. Voters evaluate a rule such as "should content residing at this URL be cached" and return a positive or negative response. By default, all content on public instances is cached except the AdminCentral UI at /.magnolia
. Server cache policy is configured in /modules/cache/config/contentCaching/defaultPageCache/cachePolicy
. The default implementation (
Default
) checks if the content exists in the cache store and requests caching if the content is not found. The alternative class,
Never
instructs the cache not to store the generated content. Server side re-caching of no-cache requests (shift reload) are configurable and set to false
by default.
Node name | Value |
---|---|
defaultPageCache | |
cachePolicy | |
shouldBypassVoters | |
urls | |
deny | |
resources | |
class | info.magnolia.module.cache.cachepolicy.Default |
refreshOnNoCacheRequests | false |
You can define a custom cache key generator or configure the default one to meet your needs. cache config contentCaching defaultPageCache cachePolicy shouldBypassVoters ttlVoters cacheKeyGenerator useRequestParameters class info.magnolia.module.cache.cachekey.DefaultCacheKeyGenerator class info.magnolia.module.cache.cachepolicy.Defaultfalse
Default cache key attributes | ||
---|---|---|
Attribute | Default | Description |
useUri | true | Use URI as part of cache key. |
useRequestParameters | true | Use request query as part of cache key. |
useRequestMethod | true | Use request method (GET/POST/HEAD) as part of cache key. |
useRequestServerName | true | Use server name as part of cache key. |
useRequestGetSecure | true | Save information whether this request was made using a secure channel, such as HTTPS as part of cache key. |
useUserName | true | Use user name as part of cache key. |
useLocale | true | Use locale (info.magnolia.cms.core.AggregationState#getLocale) as part of cache key. |
useChannel | true | Use channel (info.magnolia.cms.core.AggregationState#getChannel ) as part of cache key. |
Allows for different policies for different content types. Voters are used to define the caching rules. These policies define how long the browser may cache each content type. The time is passed to the browser in the response header. The FixedDuration option instructs the browser to cache the content for the specified length of time in minutes. Never instructs the browser to do nothing. Client cache policy is configured in /modules/cache/config/contentCaching/defaultPageCache/browserCachePolicy
.
Node name | Value |
---|---|
defaultPageCache | |
browserCachePolicy | |
policies | |
farFuture | |
voters | |
class | info.magnolia.module.cache.browsercachepolicy.FixedDuration |
expirationMinutes | 525600 |
resources | |
dontCachePages | |
voters | |
class | info.magnolia.module.cache.browsercachepolicy.Never |
default | |
class | info.magnolia.module.cache.browsercachepolicy.FixedDuration |
expirationMinutes | 10 |
class | info.magnolia.module.cache.browsercachepolicy.BrowserCachePolicySet |
The Flush policy defines when to flush the cache. The default configuration observes changes (activation, import, edit) in a workspace and flushes the cache if new or modified content is detected. Cache can be flushed completely, partially or not at all. Each module can register its own flush policy (or multiple policies) and receive notification about new or modified content in each workspace. Flush policies are informed about changes in observed workspaces. The list of observed workspaces can be defined per policy under the workspaces
subnode of each policy or all workspaces will trigger cache flush unless defined under excludedWorkspaces
subnode (default configuration). If your custom workspace doesn't affect the content of pages, you should register it under excludedWorkspaces, otherwise a change in your workspace will unnecessarily flush the cache.
Node name | Value |
---|---|
defaultPageCache | |
flushPolicy | |
policies | |
flushAll | |
excludedWorkspaces | |
forum | forum |
imaging | imaging |
magnolia-mgnlSystem | magnolia-mgnlSystem |
magnolia-mgnlVersion | magnolia-mgnlVersion |
messages | messages |
profiles | profiles |
users | users |
dam | dam |
class | info.magnolia.module.cache.FlushAllListeningPolicy |
FlushByComments | |
workspaces | |
0 | forum |
class | info.magnolia.module.commenting.cache.ReferencedPageFlushPolicy |
class | info.magnolia.module.cache.DelegateFlushPolicy |
These are actions taken once a caching decision has been made. There are three possible actions:
useCache
: Retrieves the cached item from the cache and streams it to the client.store
: Stores the response in the cache for future use.bypass
: Skips caching. This is useful for content that cannot or should not be cached.Executors can be configured at /modules/cache/config/contentCaching/defaultPageCache/executors
. Each of the executors is also responsible for configuring expiration headers.
Node name | Value |
---|---|
defaultPageCache | |
executors | |
bypass | |
store | |
useCache |
Compression is a simple and effective way to save bandwidth and speed up your site. It is a common practice used by Google and Yahoo! for example. (How to Optimize Your Site with GZIP Compression is a great general introduction to the topic.) Compression is performed in the gzip filter, configured in /server/filters/gzip
}. When a client requests a resource such as index.html
, Magnolia delivers it zipped. A typical HTML page is compressed to 20% of its original size. So if your page is 100 kB uncompressed, it is 20 kB compressed. To improve performance further, zipped content is streamed from the repository to the client rather than read into memory first.
You can configure which content types to compress. By default the gzip filter bypasses compression for HTML, JavaScript and CSS because they are explicitly selected for compression in the Cache module configuration. These types can be compressed efficiently because they are text. The decision to compress a particular content type is made with voters. Voters are used whenever configuration values are not assigned at startup but depend on rules instead. In the Cache module configuration there are three voting rules based on content type:
text/html
: HTML.application/x-javascript
: JavaScript.text/css
: Cascading Style Sheets.
Node name | Value |
---|---|
cache | |
config | |
compression | |
voters | |
contentType | |
allowed | |
1 | text/html |
2 | application/x-javascript |
3 | text/css |
class | info.magnolia.voting.voters.ResponseContentTypeVoter |
To add more content types, such as XML, create a numbered property under allowed
. Use the Internet media type (MIME type) as value. Here are some common media types:
application/xhtml+xml
: XHTM L.text/csv
: Comma-separated value.text/plain
: Textual data.text/xml
: Extensible Markup Languag.application/pdf
: Portable Document Format.As a rule, compressing the HTML, JavaScript and CSS is sufficient; it is not necessary to compress binary content such as images. During the process, the browser sends a header telling the server that it accepts compressed content: Accept-Encoding: gzip
. Note that Magnolia does not cache big binaries.
Note that while all modern browsers support compression, some older browsers do not, notably Internet Explorer 6 before Service Pack 2. To get around this, Magnolia uses a userAgent
voter that rejects compression and delivers uncompressed content if the browser identifies itself as IE6 in the User-Agent
field in request headers.
Node name | Value |
---|---|
compression | |
voters | |
contentType | |
userAgent | |
rejected | |
00 | .*MSIE 6\.0.* |
class | info.magnolia.voting.voters.UserAgentVoter |
To test your compression configuration, use a tool such as Web-Sniffer that allows you to change the Accept
, Encoding
and User-Agent
sent headers easily. Here's what the headers look like when the Magnolia demo site home page is submitted to the sniffer.
Request header:
GET /demo-project.html HTTP/1.1 Host: demopublic.magnolia-cms.com Connection: close User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9) Gecko/2008052906 Firefox/3.0 Accept-Encoding: gzip Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7 Cache-Control: no Accept-Language: de,en;q=0.7,en-us;q=0.3 Referer: http://web-sniffer.net
Response header:
Status: HTTP/1.1 200 OK Date: Fri, 23 Jul 2010 07:45:10 GMT Server: Apache/2.2.9 X-Magnolia-Registration: Registered Cache-Control: max-age=900 Last-Modified: Thu, 01 Jul 2010 14:03:12 GMT Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 3852 Connection: close Content-Type: text/html;charset=UTF-8
In the Enterprise Edition advanced caching strategies are available in a separate Advanced Cache modules .
Cache related commands are in the cache
catalog:
flushAll
: Completely flushes all caches. (Note that the imaging workspace - which technically is not a cache - is not flushed with this command.)flushByUUID
: Completely flushes all entries related to a given UUID from all available caches. This command expects repository
and uuid
as parameters.flushNamedCache
: Completely flushes a cache by name. Default cache names are default
and uuid-key-mapping
.By default, the following URLs are cached:
/.magnolia/*
which is AdminCentral./.resources/*
if magnolia.develop
property is set to false
.The system caches resources such as JavaScript files and CSS files on the author instance by default to make authoring more responsive. Disable this behavior when developing. Set the magnolia.develop
property to true
in the default magnolia.properties
file. For more complex configurations, you need to adjust the configuration under the /config/configuration/default/cachePolicy/voters
node
There are various reasons why you may wish to exclude content from cache. For example, you may have components that query an external data source dynamically. The rendered HTML changes even if the content of the Magnolia page has not changed. When we say cached content we mean the rendered output generated by Magnolia itself, the actual content of the page. When you exclude a page from cache you tell Magnolia that it should re-render that content every time the page is requested by a user.
The first option for excluding content from cache is to configure an exclusion in the cache policy. The example below excludes all pages whose URL starts with /.magnolia
. This means that AdminCentral pages are not cached.
Node name | Value |
---|---|
cache | |
config | |
contentCaching | |
cachePolicy | |
shouldBypassVoters | |
urls | |
includes | |
excludes | |
dotMagnolia | |
class | info.magnolia.voting.voters.URIStartsWithVoter |
pattern | /.magnolia |
not | true |
level | 1 |
To implement a custom cache policy, implement the CachePolicy interface and override the methods you wish to customize. The default policy:
...determines if a requested page should be cached, retrieved from the cache or not cached at all. It is called for every request and takes care of any expiration policy, that is if the page should be re-cached. The CacheFilter (or any other client component) can determine its behavior based on the return CachePolicyResult, which holds both the behavior to take and the cache key to use when appropriate.
Configure your custom cache policy class in /modules/cache/config/configuration/default/cachepolicy
.
Cache header negotiation is a mechanism that allows templates and components to influence whether the content should be cached and for how long. This mechanism can be used when it is too late to configure an exclude, but you do not wish for a page to be cached. Excludes are typically configured before it is clear what kinds of pages editors will add and what kind of content those pages will have. Cache header negotiation allows page components to influence whether the page should be cached. You can use cache header negotiation for:
The following options are not best practices but they may help you during testing. Don't use them as a long-term production strategy.
http://www.example.com?a=1
. A more subtle solution is to add bypass
to the cache filter. This ensures that no cache filter is executed on particular URLs.deny
list of the cachePolicy. Entries on the deny
list are not cached by Magnolia but are taken through the entire filter chain, meaning that other policies such as BrowserCachePolicy
can still be applied. In effect this solution, 'switches off' caching for the URL in question.Cache header negotiation uses standard cache response headers. Cache needs to be enabled for the site or cache headers have no effect on the server side cache. The mechanism is built into the Cache module and requires no extra modules. Cache header negotiation is being introduced to Magnolia in two phases:
In code, developers set the cache headers in the rendering model of a component or a template. This is the current implementation.
Example 1: Setting a cache header in Java code, snippet from AbstractFormModel .
MgnlContext.getWebContext().getResponse().setHeader("Cache-Control", "no-cache");
Example 2: Setting a cache header in a JSP template script.
<% response.setHeader("Cache-Control", "no-cache"); %>
Available in version 5.3.2 or higher.
This threshold is used to determine if a resource should be cached or not according to its size. The default value of 500K was not selected randomly, but as a result of testing that shown 98% of resources were served as fast from memory as from the repo when exceeding this value. This is mainly due to the fact that transport of such amount of data offsets time needed for accessing the repository.
You can still change this value programatically, e.g. in your custom renderer which does time-consuming operations:
MgnlContext.getWebContext().getRequest().setAttribute(CacheResponseWrapper.ATTRIBUTE_IN_MEMORY_THRESHOLD, CacheResponseWrapper.DEFAULT_THRESHOLD * 2);
You need to set this attribute before anything is written to the output.