Best Approaches to Clientlibs in AEM: Part III
The breadth of useful and innovative features within Adobe Experience Manager (AEM) covers many different aspects of creating an amazing digital experience:
Digital content and asset management? Check.The latest in customer personalization and targeted content? Check.Ability to integrate with a vast variety of technologies? Check.
What about speed? While all of the dynamic and intricate functionality AEM provides is impressive, it does impact the speed of the site. You may already know that page load time has a direct impact on SEO, revenue, customer satisfaction, and conversion rates. Load time often comes down to page design and optimizing the when and how of loading resources on a page. You’ve organized, minified, and gzipped…What more can you do!? There are a few more design tricks with clientlibs you can take advantage of if you’re looking to create extremely fast websites.
Load only what you need
Start by visualizing the types of pages on your site and components on those pages. Maybe you already have a navigation menu designed. That’s a great place to start to figure out what types of pages you have. Do you have components that are only used within that category of page?
For our example, we’ll use an eCommerce site and split the pages into different categories. These would be categories like homepage, product marketing/description pages, shopping flow pages, account management pages, and support pages. Some components are very common and used across most pages, like rich text, images, menus, and so on. Identify these and write them down under a Shared category. Then identify other components that you use only in one or two categories. Hero banner and carousels may only be used on the homepage and product marketing pages.
Now you can split up these page categories into different page components that load different groups of clientlibs. Using dependencies from Part II, we can make small chunks of javascript and css to load and cache across pages.
A marketing page could load <cq:includeClientLib js=”project.marketing.all” /> which embeds “project.marketing” components and has a dependency on “cq.jquery” and “project.shared” resulting in:
<script type=”text/javascript” src=”/etc/clientlibs/foundation/jquery.js”></script>
<script type=”text/javascript” src=”/etc/designs/{project}/shared/ clientlib.js”></script>
<script type=”text/javascript” src=”/etc/designs/{project}/marketing/ clientlib.js”></script>
This concept works particularly well if you’re aiming for an extremely fast site and minimizing total loaded file size. If mainly targeting mobile users, it may make sense to aim for a low number of requests instead by embedding the “cq.jquery” and “project.shared” in the “project.marketing.all” client library. Keep in mind that this approach will take some additional code updates if you decide later that a component should be used in another location on the site.
Check out this article for more AEM time saving tips.
Other approaches
If maintenance and static categories won’t work for your site because the components and layout of your pages constantly change, the Hybrid clientlibs approach may still be your best option. The hybrid approach results in one cached javascript file that can be used across your site because it includes all of your component javascript.
However, if your layout constantly changes and you’re worried about how big your clientlibs file has become, deferred clientlibs might be a better option. For this approach, you would remove the load all javascript clientlib (<cq:includeClientLib js=”project.all” />) from the footer and tell your components to consolidate their javascript in the footer only if they are used on the page.
Let’s say you have 50 components with javascript across your site. On your Sitemap page, you only load 5 components—a few in the header and footer, and one for the sitemap itself. Instead of loading the javascript for all 50 components, you could load the javascript for just those five.
Usually, this is implemented through the use of a custom Tag Library to wrap script, and clientlib includes of javascript at the component level. The tag library tells the server to remove the include from where it’s loaded inside the component and combine it with other deferred includes to make just one request in the footer of the page.
For example:
… [Navigation component logic]
<ici:js-defer>
<cq:includeClientLib js=”icidigital.components.navigation”/>
</ici:js-defer>
[Navigation component end]
… [Sitemap component logic]
<ici:js-defer>
<cq:includeClientLib js=”icidigital.components.siteMap”/>
</ici:js-defer>
[Sitemap component end]
becomes…
<div class=”footer” />
<script type=”text/javascript” src=”path/to/programmatically/combined/deferred/clientlib.js”></script>
</div>
The downside of this approach is that it splits up your reusable javascript clientlibs file into one for each page. Meaning that our javascript file will be cacheable only for the page it’s on, opposed to across your site like it would be in the hybrid approach. The great thing is this solution is particularly faster if your javascript takes a long time to load from cache or if there’s a reason you can’t cache the page (e.g. query parameters).
What’s next?
Keep in mind that the web is ever-changing. The HTTP/2 protocol adoption rate is growing and will replace these HTTP best practices with its own. Instead, sites may want to split back out each clientlibs request as they can all be loaded asynchronously at the same time. Even still, reducing the weight of javascript and css loaded on the page will go a long way, making your site faster.
Looking for even faster speeds? Remember when sites loaded “instantly?” So do your customers. Contact us to learn more about how we can help you develop your optimization strategy.