Expand my Community achievements bar.

SOLVED

Most performant client-side clientlib implementation

Avatar

Level 2

Hi all, 

I'm wondering what the most performant way to include client-side clientlibs is.
Example: Assume you have to develop a couple of components each including their own client-side JavaScript, like a Google Map component and a carousel component (e.g. Slick) . 

As far as I can see, there are a couple of options:

  1. Create a postloaded clientlib category which includes all the client-side logic and call it in HTL it in every page footer. 
    +: There is only one instance of the client-side script
    -: Pages not who don't need Google Maps or Slick also load the libraries, which are not needed and often take time initializing. 
  2. Embed the HTL clientlib call in the component to include the clientlibs
    +: Clear separation of client-side code per component 
    -: The clientlib will be included for every component, so if you have 3 carousels, the clientlib will be added and executed 3 times, not utilizing clientlibs to their maximum potential.
    -: Dependencies on frameworks (like jQuery) are not fulfilled since these are loaded in the page footer (as per best practice) and are not initialized yet during the render phase of the component. 
  3. Embed the HTL clientlib call in specific templates
    +: Clientlibs are not loaded on all pages, only on pages that allow specific components on the parsys.
    -: When you change the component mapping (allowing Google Maps on other templates), you need to keep the clientlib categories in line with the component mapping and dynamic changes to the component mapping (using design mode) are not possible.
  4. Resolve all components in a SlingModel when rendering the page template to figure out which components are added to the page and map these to clientlib categories. 
    +: Only the required clientlibs are added to the page. 
    +: Dynamic adding of components to templates will still work
    -: Performance impact on every page load since you will have to loop through all the nodes on the parsys. 

Am I missing another (better) option that only includes client-side JavaScripts that are required and allows code separation per component?

If not, which of these options above is considered best practice?

Thanks!

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

I would use a pragmatic approach:

  • Try to reduce the amount of javascripts loaded as much as possible and embed all smaller clientlibs into the main clientlib.
  • Larger javascript files, which are not often used on your site, offload to a dedicated javascript library.

And of course:

  • Use the versioned clientlibs of ACS AEM Commons
  • Add a long expiration time.

Jörg

View solution in original post

6 Replies

Avatar

Level 10

Most of the components are loading ClientLibs when they need to - so this would line up with #2. If a libs is only required in a specific component - then there is no need to load it for all pages. Only the component's script should include logic to load the client lib, 

Avatar

Level 2

Thanks for the reply. 

Wouldn't this mean though that the script is loaded as many times as there are components present on the page since calling the clientlib.html actually generates <script> tags at the location it is called?

In a context where you have 3 components that include a clientlib with listeners, the script would try to bind them 3 times, while the initialization should only occur once for all components. 
Let's assume these components rely on jQuery, if you include jQuery at the location the clientlibs are loaded, it's possible that jQuery is loaded very soon in the DOM rendering process, while ideally it should be loaded after all the content.

How do you deal with a situation like this when lining up with #2? 

Thanks again!

Avatar

Level 10

That is a good point - i was thinking from the perspective of 1-1. Say you had a JQuery plug-in used in a component and that component was to be used once in your site, Then you would want to load it at the component level. 

Avatar

Correct answer by
Employee Advisor

Hi,

I would use a pragmatic approach:

  • Try to reduce the amount of javascripts loaded as much as possible and embed all smaller clientlibs into the main clientlib.
  • Larger javascript files, which are not often used on your site, offload to a dedicated javascript library.

And of course:

  • Use the versioned clientlibs of ACS AEM Commons
  • Add a long expiration time.

Jörg

Avatar

Level 2

IMO, Clientlib makes sure that even if you include a clientlib multiple times, only one of its instances will be converted into <script> tag, so long as Category name is same.

Apart from dependency management challenge, I believe another issue will be a number of HTTP calls going up now since every component will now try to get it's JS file when it tries to render which could be a performance issue in HTTP 1.1 and how browsers work.

I would recommend going with template specific clientlibs since you will have less number of templates but more pages and browser will be easily able to cache it on the very first page using that template. Template could be as hardened as possible for example asking the designer to lock what all components can be part of this template. This approach is more inline of your #3 approach.

Avatar

Level 2

I would recommend:

1. Writing template specific client libraries.

2. Consolidating all your client libraries basis component inclusion using custom code (that would be executed once in application lifetime) in to a single library and loading them at the end of the page.

3. Use caching if size of the client lib increases.

4. Above would not be applied for the third party libraries. And those would be loaded before solution libraries.