View Caching

December 21, 2021

Jahia has multiple caching mechanisms that help deliver great throughput. One of the most efficient caching is the View caching. When handled correctly but the View developer, it should be transparent to content authors, allow for highly dynamic content to be displayed, and ensure great website performance.

Before you begin

Jahia modules rely on Java and Maven. The key requirements are as follows:

  • Access to a local Jahia system or the free cloud trial from Jahia
  • Oracle JDK 11 or OpenJDK 11
  • Maven 3.3+

If you haven't completed it, please refer to the Content type rendering tutorial before proceeding with the View caching one.

What you will learn

This tutorial is intended to get you started working with the caching strategy of Jahia. It will help deliver fast and reliable web content rendering.

Why do I need to manage the cache ?

By default, all the views are going to be cached the first time they are displayed on the live site. This cache entry is going to be flushed after 30 minutes with no access. Depending on what is displayed by the view, the cache entry might not be okay to be displayed to all visitors.

Imagine the following view:

Welcome ${renderContext.user.properties['j:firstName'].string}!        

Depending on the first user to access the page (let's call this person 'Frank'), all following visitors will be displayed Welcome Frank! Not great.

Fortunately, managing the cache is straightforward. The documentation is available here. The following tutorial will show you how to quickly solve the most common cache challenges.

How to manage the cache?

There are two concepts involved:

  • View configuration with 'properties' file
  • Rendering delegation

Cache configuration with .properties file

Each view can be configured by creating a .properties file of the same name, in the same folder. Eg:

src/main/resources/jnt_introBlock/html/introBlock.jsp  
src/main/resources/jnt_introBlock/html/introBlock.properties        

The properties file will contain cache configuration for the associated view.

Some configuration examples are:

  • cache.expiration = 30: the cache expires after 30 seconds
  • cache.mainResource = true: one cache entry will be created per page where this content is displayed (useful for content displayed in multiple pages, such as navigation menus)
  • cache.perUser = true: useful when displaying content specific to a user

Rendering delegation

A view should only display content that belongs to the node it displays. In other words, if a view displays content aggregated from multiple content items, you are doing something wrong.

Rendering delegation is fairly simple: use the <template:module> JSTL to include other views in the current one.

Practical cases

This section will provide an example of the most common cache challenges.

Managing the cache when displaying content

Imagine the following view:

<%@ page language="java" contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:if test="${currentNode.properties['title'] != null}">
   <h2>${currentNode.properties['title'].string}</h2>
</c:if>

In this case, only CMS content is displayed, and you don't have to do anything related to the cache. Jahia will automatically invalidate all cache entries related to the piece of content when it is modified.

Managing the cache when displaying content that does not belong to the currentNode

Instead of doing this:

<div class="articleTitle">${currentNode.properties.title.string}</div>
<div class="author">${currentNode.properties.author.node.properties['j:firstName'].string}</div>

Where the view of an Article tries to display the first name of its author.

Instead, the right way of approaching it is:

<div class="articleTitle">${currentNode.properties.title.string}</div>
<template:module node="${currentNode.properties.author.node}" view="firstname" />

And have a file jnt_user/html/user.firstname.jsp created with the following content:

<div class="author">${currentNode.properties['j:firstName'].string}</div>

Managing the cache when displaying content related to a specific user

When displaying properties belonging to a user, or when a view displays stuff specific to a user, a specific cache treatment needs to be applied.

For instance:

Hi ${renderContext.user.properties['j:firstName'].string}! Here are your bookmarks:

<jcr:sql sql="select * from jnt:bookmarks as bookmark where ISDESCENDANTNODE(bookmark, ${renderContext.user.localPath})" var="bookmarks" />
<c:forEach items="${bookmarks}" var="bookmark">
   <template:module node="${bookmark}" />
</c:forEach>

Will not work out of the box, and the bookmark of the first visitor accessing the page will be displayed to all users.

A .properties file containing cache.perUser = true will solve the problem.

Displaying dynamic content

Dynamic content that is not related to the CMS' content is the only occurrence where the cache cannot be used and must be disabled.

Take the following example:

The current time is <fmt:formatDate type = "time" value = "${now}" />

The output of the view is going to change every second and shouldn't be cached. Same thing goes when the JSP is displaying content from a different source (aggregated from a web service, performing an operation…).

In this case, the cache needs to be shorten or disabled with the following property: cache.expiration = 0

 

Congratulations! You learnt how to enhance the performance of your sites while serving highly dynamic content. Next: learn how to use Roles and Permissions.