Sunday, June 25, 2017

ClientLibs in AEM6.3 - Part2


Hello Everyone,

In the ClientLibs - Part1 blog , we have already gone through clientlibs in detail. But still, there is a question in everybody’s mind, that what is the ideal way to create client library folders ?

So we are going to discuss some of the approaches, with its pros and cons:

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

allowProxy.PNG
Fig - allowProxy property in clientlib folder

  
url.PNG
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”  


dialog.PNG
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 :


  1. ?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.


debug.PNG
Fig - debug the clientlib in the browser

Let’s get this concept with the help of an example:

For Example: There are two clientLibraryFolders.
  1. /etc/clientlibs/clientlib2
  2. /apps/aem-developer/clientlib1
Clientlib1 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.

css.PNG
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.

js.PNG
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.


test clientLibrary.PNG
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       

rebuild.PNG
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.


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 which are not supposed to be exposed to 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 in the page along with the dependent clientlib.


Till Now, We have covered a lot on client Libraries. But still something is left for you to come.So stay tuned.
If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com
Hope it will help you guys !!
Thanks and Happy Learning .😊

9 comments:

  1. Great article..Its always a pleasure to read your articles !!

    ReplyDelete
  2. Thank you Kaushik. Many More to come.

    ReplyDelete
  3. Dint know about allowProxy. Good to know.. :)

    ReplyDelete
  4. @Vivek,Good to see your comments here.And yes I also didn't know,while studying about the topic,I came to know. :-)

    ReplyDelete
  5. If you have time, can you explain/elaborate the following statement from your article? How do you rewrite it properly?


    "References to images located unter /apps/ should be properly rewritten by Client Library Manager so that those are loaded through /etc.clientlibs/myapp/clientlibs/images/bg.png"

    ReplyDelete
    Replies
    1. The section was bit messy, you highlighted and bit wrong also. Updated the section and add a video on youtube for the same. If you still have confusion, please let me know.Thanks.

      Delete
  6. It is always very fruitful to read your articles thanks for this great content.

    ReplyDelete