I'm trying to include clientlibs with async or defer attributes in the script tag. However, I also want to ensure that each clientlib is not loaded more than once. So if I include the clientlib within a component's code and the component is used multiple times on a page, the script tag should only appear in the first instance of the component.
The default way of including clientlibs (using /libs/granite/sightly/templates/clientlib.html) does seem to prevent the same script from being loaded more than once, but doesn't support async/defer.
I was able to get async/defer working using the https://github.com/nateyolles/aem-clientlib-async example that I've seen mentioned here. However, this code does not prevent the script from being loaded and executed multiple times if there are multiple components on the page.
Does anyone know how I might accomplish this? I would appreciate any insight!
All Adobe reference points suggests to concatenate your clientlibs to a single file and gets included in your template header and footer. For example, refer to /apps/weretail/components/structure/page/customfooterlibs.html /apps/weretail/components/structure/page/customheaderlibs.html
In case you have so many heavy clientlib components which you don't want to load on all the pages, you can follow the below approach.
1. Categorise your component clientlibs wth 'categories' property based on the grouping of components. You can think of core, homepage etc 2. Define templates for your usecases and overlay customfooterlibs and customerheaderlibs to include the required category.
But this goes against the capability of editable templates where you can update the policy to add a new component to the page. So overall it differs as per the use case of each project based on the priority between page load and agility as well
Thanks for the response. The only way I could find of doing #1 (including clientlibs on a per-component basis) involved putting the include in the component HTL, rather than in the document head or at the end of the body. This is why I started to look into how to add async/defer in the first place, since I didn’t want a script in the middle of the page to block the rendering.
Ideally, I wanted to keep the number of requests down by creating bundles for groups of components that are loaded as needed rather than a separate file for each component.
The reason I didn’t want to do #2 (throw everything in a single component bundle) was to keep the page size down and not load a lot of JS/CSS that is never used.
I’m relatively new to AEM development so it’s possible that I’m missing something. I did consider whether creating different static page templates and loading different bundles there would be the way to go - this might be a more "AEM way" of doing things? Potential issues with this would be a) being overly restrictive for marketers in terms of what components they can use, and b) situations where a resource-heavy component is only used in a small percentage of pages of its template type.
Thanks again, looking forward to hearing your thoughts on this!