March 30, 2020
Estimated Post Reading Time ~

ClientLibs in AEM6.3 - Part2

In this post, we will go over the pros and cons of clientlibs in detail.

➤ Unified Approach: This is also called as centralised approach. In this approach, we will create a global clientlibs in “/etc/clientlibs” and it just need to included it in our base page.

Pros: If the project is so small, then we can go with the Unified approach.
Cons:This approach is having a centralized clientlibs.So It is very difficult to manage and debug large clientlibs.

➤ Modular Approach: In this approach, we will create a global clientlibs in “/etc/clientlibs” and create some component level clientlibs. These component level clientlibs should be embedded in global clientlibs.

Pros: Very maintained and managed clientlibs.
Easy to debug. Number of network calls will be very less.
Cons:  If there is a component level clientlibs, and the component is not dragged on a page, still the clientlibs will get loaded. It will degrade the performance of the page.
We can’t directly include the clientlibs written in /apps on the page as on publish, anonymous user restrict /apps folder.

➤ Hybrid Approach: This is something new which AEM 6.3 provides.
There is a concept of “proxy servlet”, with the help of this we can directly include the clientlibs(present under “/apps”) on a page.

But How?
1. Make a clientlibs in /apps.
2. Add a property allowProxy Boolean true in clientlib folder node.
3. Now include this clientlibs in any page.
4. The clientlibs stayed in /apps can be accessed through /etc. clientlibs So there is no need to embed the clientlibs in global clientlibs under /etc


Fig - allowProxy property in clientlib folder


Fig - without embed in /etc clientlibs, load the /apps level clientlib

In order to better isolate code from content and configuration, it is recommended to locate client libraries under /apps and expose them via /etc.clientlibs by leveraging the allowProxy property.

Note: Don’t forgot to change the dispatcher configuration for /etc.clientlibs.

Adobe recommends that the clientlibs should exist under /apps and exposed via /etc. clientlibs using proxy servlet. But this approach still respect the best practice that anything should not be served from /apps or /libs on the public sites

Note: If your clientlib under /apps has css files that reference images
(Example background-image: url(/apps/myapp/clientlibs/images/bg.png)), those won't
be loaded.
So what to do?

If you want to load images and fonts in the clientlibs, make sure to use relative path in place of absolute paths.One more important point to note that put all the fonts and images under “resources” directory, else fonts and images won’t be loaded. So ideally the folder structure should be like:

/apps/myproject/clientlibs
----------css
----------js
----------resources
-------img
-------fonts

[This feature also works perfectly fine with AEM 6.2 with SP1 CFP13 Service/Feature Pack]
Pros: Hybrid approach overcomes the problem of modular approach of not including /apps clientlibs directly on any page by using proxy Servlet.

Cons: The network calls may be high,if you include component level clientlibs on component’s html.

Conclusion: All the approaches has it’s own pros and cons . It’s not always the idea of having minimum number of n/w calls ,sometimes modularity is also important.So this is up to you, which approach you can use wisely use with minimum cons.

⟹ No of Network Calls ∝ Modularity of clientlibs

How to load touch UI Specific Clientlibs
Problem Statement: In the Touch UI Dialogs ,If there is a need to put some validation on fields or we just want to add some CSS,then use “cq.authoring.dialog” clientLibrary.This clientlibs is automatically loaded when the dialog opens.So, No need to make an entry of it on any page.

This created a performance issue because if the clientLibrary is so big and it is getting loaded in all dialogs regardless of dialog needs it or not.

Solution: Using extraClientlibs Property: In the cq:dialog node of a dialog, add these properties:
1. Name:extraClientlibs
Type: String[]
Value: ClientLib_Category_Name
2. Name: mode
Type:String
Value:edit”

Fig - extraClientlibs and mode property in dialog

Debugging Tools
In AEM projects,There is always a challenge in debugging clientlibs. So There are a lot of tools provided by aem to help developers :

?debugClientLibs=true: If there is a need to debug how many clientlibs are getting embedded in the main clientlibs,

Just add a query parameter in the page URL. “?debugClientLibs=true”, there will be separate network calls for each clientlibs. So debugging of js/css individual files will be easy.


Fig - debug the clientlib in the browser

Let’s get this concept with the help of an example:
For Example, There are two clientLibraryFolders.

/etc/clientlibs/clientlib2
/apps/aem-developer/clientlib1Clientlib1 is embedded in clientlib2.


When we add “?debugClientLibs=true” in the page URL and go to the source tab of browser:

All the embed files of css can be seen while going in clientlib2.css?debug=true.

Fig - see the embedded clientlibs of css in browser console

All the embed files of js can be seen while going in clientlib2 .js?debug=true.

Fig - see the embedded clientlibs of js in browser console

2. There is a component available in /libs/cq/ui/components/dumplibs/dumplibs.test That shows all the clientlibs folder of the system in a page.

You can directly go to the page by using this url http://localhost:4502/libs/granite/ui/content/dumplibs.html and see all the clientlibs, its dependencies and embed clientLibraries.
If you want to know about a particular clientlibs,which css and js files are getting loaded, add a selector "test" and see the results here: http://localhost:4502/libs/granite/ui/content/dumplibs.test.html

Fig - check which js and css in any clientLibrary

There is always a cache issue with clientlibs, when you make any change in files (CSS/JS),the changes doesn’t reflect on pages,because AEM cache the clientlibs under “/var/clientlibs”. If you want to rebuild the clientlibs or clear cache,Go here: http://localhost:4502/libs/granite/ui/content/dumplibs.rebuild.html


Fig - Invalidate clientlibs cache and rebuild

The below link shows the table of all the clientlibs, its dependencies and embed client Libraries and validates it (whether the embed and dependencies will exist or not,or they exist for a particular category type i.e., css/js or not) with different color codes.

http://localhost:4502/libs/granite/ui/content/dumplibs.validate.html

Dependencies Vs Embed
This is one of the most tricky question and people are used to be very confused about it. So what is the difference b/w these two and when to use what?

Embed: You have learned about modular approach of using the clientlib.So we used to say that we create a centralized clientLibrary and embed all component level clientlibs in that.

So have you thought,why embed not dependencies
Let’s get an example of it.

1./apps/myproject/component/A
2./etc/clientlibs/test/B

Here A and B are clientLibraryFolders.
If you embed A in B,There is only a single call and the content of A will be embed in it.

/etc/clientlibs/test/B.css

If you make A as a dependencies to B,There are two n/w calls,

/apps/myproject/component/A.css
/etc/clientlibs/test/B.css
While loading these clientlibs in publish,anonymous user don't have access to /apps. So the first network call will give 404.

Note: Embed is usually used for minimizing requests and for accessing clientlibs that are not supposed to be exposed to the public.

Dependencies: This is a usual scenario when our js/css is dependent on some third-party libraries like bootstrap, jquery, angular, so we add them as dependencies in our clientLibrary.

So again, why dependencies not embed?
If we embed all these libraries in project-level clientlibs,There is only a single n/w call and it will spoil all the visibility of my clientlibs and it will be very difficult to debug custom code with the libraries code.
Note: This defines the other categories that the current clientlib depends upon. The dependencies will be included on the page along with the dependent clientlib.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.