banner-Versioned-Client-libraries.jpg

Versioned Client libraries – Adobe Experience Manager

Mar 19th, 2020 | Uday Patel

Marketing Technology teams often find themselves juggling between improving performance by using tools like caching, compression and CDNs while ensuring their marketing teams can publish updates to their sites almost instantaneously.

As a developer, we need to make sure every page of the website loads faster and one of the ways to achieve this is by caching the CSS and Javascript files on the client side for a longer TTL (Time to Live). This will improve the performance of the website drastically as the user’s browser will not fetch js and css files as they move across different pages on your site. But, if we cache the CSS and JS files for a long time by increasing the TTL, if the marketing team needs to push an update your users will not get those immediately, moreover they might even encounter or run into issues when browsing your site. If we keep the TTL short, that doesn’t necessarily help with the reducing load for your servers and still causes inconsistencies because different middle layers such as CDN, users’s browser can potentially end up caching the files for different times.

What if we want to cache the client libraries in the client browser and reliably recache only if there are changes in the javascript/css?

The solution to this problem is to utilize fingerprinting. Adding a fingerprint to the path of your CSS and JS files every-time the contents of those css or js change can allow you to set a long TTL and, avoid the need for cache busting because as soon as you update your CSS and JS Files, the fingerprint will change thus, user will load the new css/js file and cache those.

ACS Adobe Experience Manager Commons has a solution for Adobe Experience Manager to add fingerprints to your Clientlibs. Versioned Clientlibs uses a Sling Rewriter and appends a unique ID (MD5) to the path of the clientlibs, forcing them to recache only if there is a change in the client libraries. This approach makes it more reliable than using the lastModified property to determine when to recache.

For example:

Before

<script type="text/javascript" src="/etc.clientlibs/clientlibs/jquery.js"></script>
<link rel="stylesheet" href="/etc.clientlibs/app/clientlibs/clientlib-base.css" type="text/css">

After


<script type="text/javascript" src="/etc.clientlibs/clientlibs/granite/jquery.ACSHASH5e8d3382f82b03b0bf3fea3024eecd61.js"></script>
<link rel="stylesheet" href="/etc.clientlibs/app/clientlibs/clientlib-base.ACSHASHf14afbb8566adf69b983fd1a90d28b5d.css" type="text/css">

Comparison between Versioned and Normal Client Libraries:

Versioned Client Libraries Normal Client Librarie
Longer TTL (highly cacheable) Short TTL (reduced cache time, performance impact)
New URL/fingerprint for clientlib is generated if clientlib change The path remains the same even if the content of css have changed – forcing you to clear dispatcher, cdn, browser cache

Implementing Versioned Clientlibs

  1. Navigate to /libs/cq/config/rewriter/default from http://localhost:4502/crx/de/index.jsp
  2. To implement versioned-clientlibs at project level, Navigate to your project app folder.
    /apps/
  3. One of the most important requirements for the versioned-clientlib configuration is that the node must be inside a four-level path that ends in config/rewriter.
    /apps//config/rewriter
  4. Copy the below content to the configuration node created inside the above mentioned folder path. Name the configuration folder default.xml/versioned-clientlibs.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
contentTypes="[text/html]"
enabled="{Boolean}true"
generatorType="htmlparser"
order="1"
serializerType="htmlwriter"
transformerTypes="[linkchecker,versioned-clientlibs]"/>

Save the changes and make sure to restart the Adobe Experience Manager instance for the configuration to take effect.

To validate if the configuration is correct go to Sling Rewriter web console.

http://localhost:4502/system/console/status-slingrewriter

Successful configuration will look like below.


sling-rewrite-1.jpg

Additionally, ACS Commons also provides OSGi Configuration to enable/disable clientlib versioning.

http://localhost:4502/system/console/configMgr

The configuration is available under "ACS AEM Commons – Versioned Clientlibs Transformer Factory".


osgi_config-1.jpg

Now the clientlibs will be recompiled every time there is a change and will be re-cached in the client browser.

Unfortunately, ACS Commons rewriter does not support the following:

  • URIs embedded in CSS or JavaScript, including: background-images, web fonts, etc.
  • Relative URIs, e.g. etc/clientlibs/mysite/styles.css
  • URIs including a scheme, e.g. http://example.com/etc/clientlibs/mysite/styles.css and //example.com/etc/clientlibs/mysite/styles.css
  • URIs to non-Adobe Experience Manager HtmlClientLibrary resources, e.g. /etc/designs/mysite.css
  • Tags contained in conditional comments.
  • ClientLibs included by Javascript (e.g. when leveraging the property channels
  • Are you looking for help with your Adobe Experience Manager implementation? Reach out to hello@initialyze.com.