Search code examples
javascriptcssperformanceaemclient-library

Component based clientlibs AEM


Is it better to split up clientlibs by components if it means more calls to the server?

I.e. using

<%@taglib prefix="ui" uri="http://www.adobe.com/taglibs/granite/ui/1.0" %> <ui:includeClientLib categories="mqd.component.accordion" />

in the <component>.jsp instead of compiling all the CSS in a single stylesheet.


Solution

  • From what I know, this is more of a decision based your use case, there is no one approach which fits all the scenarios -

    Loading CSS at component level

    When you load CSS at the component level, it is not available in the HEAD section when the page rendering process kicks off. It will only render your component CSS when it encounters it somewhere in the body tag.

    Conditionally loading CSS based on the component is not available by default, you would have to write custom logic to achieve this. From this post,

    One way to achieve this is to intercept that behaviour. Use a filter and buffer all data written to the output buffer in memory. Then you can render safely all components and if you encounter your special component you can set a flag in the request attributes. The filter can then check for these attributes, change the buffer accordingly and then send everything out. That approach is a bit risky, because it can consume a lot of memory. And it changes the rendering performance and behaviour of your page. But it might be worth a try.

    Also, with component level CSS, you would have to ensure the styles for a component don't affect styles for another component, i.e. you would have to use narrow selectors to do this and ensure you don't break anything else in the process.

    Also, with component level CSS, you would have to ensure the styles for a component don't affect styles for another component, i.e. you would have to use narrow selectors to do this and ensure you don't break anything else in the process.


    Other approaches

    Using page components - If you have a component which has a lot of styles and you don't want this to get loaded on every other page, you can look at using page components(different templates) to achieve this. Each page component can load a different group of clientslibs based on its use.

    Using deferred clientlibs - If your layout constantly changes and you’re worried about how big your clientlibs file has become, deferred clientlibs might be a better option. Example from the link listed below -

    … [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>
    

    Whatever approach you take, ensure caching, page load times, maintenance, performance, etc are taken into account.


    Further read

    Best approaches to clientlibs in AEM

    CSS best practices in clientlibs