AEM Page Speed Optimization

Cristian Romero and David Truchet, November 24, 2020

Executive Summary

As the internet continues to expand at mind-numbing speeds (about 27,000  new users every hour according to ourworlddata.org) - there has been a steady increase in the amount of time individuals are spending  online.  With so many users logging in from around the world (under a variety of network conditions and bandwidth limitations), it has become increasingly important for companies to design streamlined experiences that present information in efficient and unobstructed ways.

Creating content and assets that load quickly isn't just good practice, it is practically become a requirement. For example,  Event Google is on a quest to improve search results that are not just based on content but also on the page load speeds and performance of web pages.

Adobe Experience Manager (AEM) is a powerful Content Management System with a multitude of tools and services that help companies deliver exceptional experiences to their customers. With a few helpful tips and tricks, we can help you tune your content inside of AEM to make it accessible in the quickest way possible.


 

Want to improve page speed loading?

There are several tools on the market that can help us asses the primary issues with our pages, but Lighthouse has proven to be one of the best available.

Lighthouse is an open-source, automated tool for improving the quality of web pages and is part of Google Chrome Developer Tools. You can run Lighthouse against any web page, public or requiring authentication. It has audits for performance, accessibility, progressive web apps, SEO and more. Once in the Lighthouse tab, you can run an analysis to understand what page speed issues need to be addressed.

pic1

There you can select several options for your analysis, but we want to focus on the Performance Analysis, which will assess our page speed. This analysis can be done in a page that is already available on the internet or against a local development environment to detect any issues before releasing a page. It’s advisable to run the Performance Analysis in both the pre & post publishing stages since some issues cannot be reproduced in local environments.


 

Understanding the metrics

The analysis will provide you with a score and the criteria used to evaluate the page. Important issues that affect your page speed are colored in red, warnings or page optimizations that can be improved are shown in orange, and criteria within the acceptance for the metric are shown in green.

A screencap of Chrome dev toolsA screencap of Chrome dev tools

In addition, each section will show the resource(s) that are involved in the criteria - as well as a link to documentation - which shows how that metric is being calculated, and how to improve it.

A screencap of Chrome dev tools


 

Most common issues and how to address them

 

1) Enable JS minification and compression

Minification allows us to reduce the size of the files being requested to the server. Some libraries may already come minified - but that is the exception, not the rule.

AEM provides a service to enable minification on the instances which in time will reduce the size of the Javascript (JS) files being requested, improving the loading time of the pages. Details and examples on how to enable minification can be found here.

 2) Defer loading of Clientlibs to improve speed and avoid blocking other resources

Clientlibs in AEM is a concept which allows you to store client side code in the repository, organize it into categories and then decide when and how each category code is served to the client.

Clientlibs are usually groups of JS files and Cascading Style Sheets (CSS) that often create large file sizes. Traditionally, the inclusion of these client libraries are comprised of the CSS that is being loaded in the header of the base page of your page templates, and the JS which is being loaded in the footer of the template base page.

The above process is performed to make Clientlibs available to all pages created from templates. CSS is placed in the header so when the content HTML is compiled, it will have the CSS ready. JS is placed in the footer so when the HTML is compiled it can fetch all the elements it needs.

However, a word of caution - JavaScript is considered a "parser blocking resource". This means that the parsing of the HTML document itself is blocked by JavaScript. When the parser reaches a <script> tag, whether that be internal or external, it stops to fetch (if it is external) and run it. Unfortunately, AEM does not provide a default way to defer its loading.

Luckily, there is an alternative. We can make use of an “Async clientlib library ” to defer the loading of the JS. Doing so, vastly improves performance. You can get the source code from here an add it to your project under apps:

Screencap of AEM file hierarchy

After adding the source code to your project, you can simply include the new Clientlib with a defer modifier to defer the loading of your JS in your pages. In this case, we named it Clientlib async to avoid issues with other Clientlibs.

<sly data-sly-use.clientLibAsync="/apps/project-name/sightly/templates/clientlib.html">
    <sly data-sly-call="${clientLibAsync.js @ categories='dependencies', loading='defer'}"/>   
    <sly data-sly-call="${clientLibAsync.js @ categories='vendor', loading='defer'}"/>
    <sly data-sly-call="${clientLibAsync.js @ categories='main', loading='defer'}"/>
</sly>

 3) Identify big libraries used for single pages and manage them into their own client library

There are some cases where we need to customize certain components to make use of third party libraries.

Normally, all of the components are combined into a bundle that contains the libraries not being generated by developers - usually into a ‘vendor’ Clientlibs. Since vendor libraries typically provide support for the customized component, we develop ones that are loaded with the main JS into the page template (you might have noticed in the previous example the deferring of the vendor Clientlib)

In some cases there are a few assets that only are used in one or two pages, so having them bundled with all the other support JS can lead to huge files that can impact our loading speed in a negative way.

Making use of the deferred loading, we can solve slow loading issues by creating a single client lib for just the bigger files. For this example, we have identified this library from Amazon that enables the user(s) to upload or download files directly from Amazon Web Services (AWS).  Minifying and compressing it's size, and rounding the 1.7MB, could severely impact the normal loading of other pages that do not require this feature.

Instead, we loaded it with the other vendor libs by moving it into its own Clientlib.

Screencap of AEM hierarchy

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:ClientLibraryFolder"
    allowProxy="{Boolean}true"
    categories="[project-name.amazon]"/>

Please notice the allowProxy property, this will allow your client lib to be accessed through a dispatcher. Then we just include it in the component where it needs to be used.

<sly data-sly-use.clientLibAsync="/apps/projet-name/sightly/templates/clientlib.html">
    <sly data-sly-call="${clientLibAsync.js @ categories='project-name.amazon', loading='defer'}"/>
</sly>

4) Measure your performance for your i18n Granit Dictionary

Being a multisite and multi-language framework, AEM provides developers with tools to handle the internationalization of content, making it reusable.

Usually AEM developers have a Clientlib where all the AEM tools are included; normally we call this Clientlib dependencies (again you may have noticed the deferred loading for this in the first example).

AEM provides a Javascript API to make the i18n tools accessible from Javascript. This requires the inclusion from the client library granite.utils into our dependencies Clientlibs. The problem with this is that all the dictionaries are included - not just the one related to your project. In addition, each language you add will increase the size. This will make your JS file containing the dictionary information to be very large, which of course, affects your page speed scoring. 

To avoid this, we recommend getting the dictionary information from a service that leverages the JAVA i18n API. If you want to know more about how to do this, please reach out - we'd be happy to explain further.

5) Enable font swapping for Google and Typekit fonts.

Most modern websites use one or more rich fonts to display content and deliver a more enjoyable experience to users.

Rich fonts are usually loaded as independent resources,  some of which can take a significant time to load and render. This can cause negative scoring for page speed metrics. However, making the content readable can improve the SEO for the pages.

Font swapping allows web pages to display text with a fallback font while the rich fonts or font-faces are being loaded.

Google Fonts:
Font swapping can be enabled by adding the "&display=swap" query parameter to the google font resource url.

Typekit:
Typekit allows you to customize the font loading from the font website.

6) Preload Rich Fonts

Another enhancement that can be done to improve page speed performance is preloading rich fonts. Preloading fonts allows you to fetch the fonts prior to the rest of the main page content, this helps to prevent issues like font flicking or render blocking content issues detected from Lighthouse.

Some fonts can be preloaded just by adding rel="preload" into the link tag - although, sometimes the font resources are included inside the CSS  so rel="preload" by itself won’t work. In those cases, you can preload the CSS and then tell the browser that you are actually including a css file so it can make the CSS available for the compiled HTML. This can be done changing the rel of the resource at the onload browser event:

<link rel="preload" as="style" href="http://somefile.css" onload="this.rel='stylesheet'">

 

Conclusion

Our AEM experts recommend preparing a list of key metrics (important to you) prior to running Lighthouse, to ensure good site performance for page loading on AEM sites. It's also important to be up to date with new AEM features or releases that can provide options to improve your code/project performance.

Finally, there is no unique recipe to ensure optimal page speed because technology is always evolving. Having a clear understanding of how you can measure page speed/optimization, will go a long ways to helping you achieve lightning-fast page loads - keeping your viewers happy.

Have questions on how we can optimize your AEM website? Give us a shout today!