Ad Code

Showing posts with label client-side libraries. Show all posts
Showing posts with label client-side libraries. Show all posts

Sunday, July 9, 2017

Adobe Granite HTML Library Manager : A Configuration for ClientLibs


Hello Everyone,

This is one of my most awaited blog,So I am glad to share this with you all.

ClientLibs is having an OSGi Configuration in the felix console named:
Adobe Granite HTML Library Manager
Here ,We are going to explain each and every option in this configuration in detail.

1.Minify:
  • If we checked minification,it will compress all the js/css files by removing all the spaces and extra lines of files.
  • To enable this configuration in Production server is mandatory,because it will decrease the  response time of the page.But not use in Dev Server,because css/js files will become difficult to debug.
Check the response time of every network call in the below images.
beforee min.PNG
Fig- Network Calls(CSS/JS)Before Minification 
after min.PNG
Fig- Network Calls(CSS/JS)AfterMinification 
  • It minifies all the css /js files by renaming it like fileName.min.js.
Minify.png
Fig-removes extra space after minification

2.Debug:

  • This configuration is checked in Dev Server,because this configuration doesn’t concatenate the clientlibs and serve js and css files individually.
  • Helps in debugging.
  • This will prevent the CQ clientlibs files from being combined into one file, and makes troubleshooting JavaScript and css issues significantly easier.
  • Enable this configuration is equivalent to adding ?debugClientLibs=true.

3.Gzip:

  • This is also a mandatory configuration in Production server because it also helps in loading the page quickly.

Without Gzip:

unzipped request.PNG
Fig-Response Without Gzip

In the above diagram:

  • The browser requests a file index.html from the server.
  • The server provides the html as a response.
  • The response provides a 100KB file and Browser displays a page after downloading so much data.

Let’s find out a better solution.
The Server is sending a large amount of data.If we have a large file and we need to send it to someone,what we use to do?
We just Zip it and send it to the receiver.So if we could send a zip file to the  browser,it will save a lot of download time and bandwidth.
How GZip works?
  • Capture.PNG
    Fig-Reduced Response after GZip
    The browser sends a header telling the server it accepts compressed content (gzip and deflate are two compression schemes): Accept-Encoding: gzip, deflate
  • The server sends a response if the content is actually compressed: Content-Encoding: gzip
If the server doesn’t send the content-encoding response header, it means the file is not compressed (the default on many servers). The “Accept-encoding” header is just a request by the browser, not a demand.
Our job is to configure the server so it returns zipped content if the browser can handle it, saving bandwidth for everyone and giving us a happy user.
before Gzip.PNG
Fig-Network calls without Gzip
withZipping.PNG
Fig-Network calls withGzip
An ideal Request and Response for Gzip is:
zip.PNG
 Gzip,saves a lot of bandwidth and the response time of each network call.

Note: While enable Gzip in the OSGi Configuration,activate the bundle (Adobe Granite Ui Clientlibs Bundle) and clear the cache.Sometimes after enabling it, It serves the request from the cache.So to clear the cache is important.Also don’t forget to check the Accept-Encoding in the request headers and Content-Encoding in the response headers.
The Demonstration video on Minify, Debug and GZIP :

4.Timing: This enables the JS Load timing statistics.
So add a query Parameter ?debugClientlibs=true in the page url and hit Ctrl+Shift+U.
timing.PNG
Fig:Timing
5.FireBug Lite Path:Path in the workspace where the firebug-lite.js file is located. The script should make sure it does not activate if the real firebug is present. Default: "/libs/widgets/cq-widgets.js/files/endorsed/ firebug/firebug-lite.js "
Browsers has online plugins to install FireBug Lite in the browser that help to debug the css/js files.So the workspace firebug-lite.js will executed if it doesn’t find the file in the browser.

6.Debug Console: To activate this configuration is equivalent to adding "debugConsole=true" in the page Path.If we activate this configuration, FireBug Lite gets activated in the browser.
7.Force CQURLInfo:
Enabling this configuration provides "CQURLInfo" jquery object in the AEM page console.If disabled,this object will come as "undefined" in browser console.
CQURLInfo.PNG
Fig-Implicit Object CQURLInfo in the AEM Page
8.Max Age:This directive specifies the maximum time in seconds that the fetched response is allowed to be reused from the browser cache within that time of the request. For example, "max-age=50" indicates that the response can be cached and reused for the next 50 seconds.
cache-age.PNG
Fig-Max Age in the Response Header
You can check the cached files in chrome from here “chrome://cache/”.
9.Allowed Library path:This configuration indicates that from which locations clientlibs are allowed to be loaded.The default values are “/apps,/libs,/etc”.
allowed Library.PNG
Fig-Allowed Library Path
The Demonstration video on CQURLInfo, Max-Age and Allowed Library Path:


10.JS/CSS Processor Default Config:
The default value of this configuration is "min:yui".
The full form of yui is  Yahoo! User Interface Library.
  • According to Yahoo!'s Exceptional Performance Team, 40% to 60% of Yahoo!'s users have an empty cache experience and about 20% of all pageviews are done with an empty cache.
  • This fact outlines the importance of keeping web pages as lightweight as possible. Improving the engineering design of a page or a web application usually yields the biggest savings and that should always be a primary strategy.
  • With the right design in place, there are many secondary strategies for improving performance such as minification of the code,
So YUI is a tool that helps in compression of js/css files.
processor.PNG
Fig-JS/CSS Processor
  You can use any other compressor as well, As i tried with min:jquery. You can find alternatives of yui from here https://w3techs.com/technologies/compselect/js-yui.

11.Max Data URI Size: The minification of css-files can auto-inline small resources (e.g. icons). The config-parameter “htmllibmanager.maxDataUriSize”  steers maximum size for resources to be auto-inlined.

Let’s understand this with an example:
I have a css file like this:

#tiny-icon { height: 32px; width: 32px; background-image: url("tiny-icon.gif"); }
If sample-icon has a size of 360 bytes. With maxDataUriSize <= 360, the minified css file will look: 
#tiny-icon{height:32px;width:32px;background-image:url("test-alex/tiny-icon.gif")}
With maxDataURI Size > 360, the icon will be auto-inlined as data-url:

#tiny-icon{height:32px;width:32px;background-image:url("data:image/gif;base64,R0lGODlhIAAgAIQQAEeczSqmzligoGmarl6khnCdy3CpaBj
The format of data URI is:

data:[<mime type>][;charset=<charset>][;base64],<encoded data>

To understand the benefits of data URI, You can go to this website.
The Demonstration video on Max Data URI Size:

Note: Sometimes the configurations may not work because some of the configurations gets its value only when bundle is activated.So just restart the bundle shown below and everything will work fine.
bundle.PNG
Fig-Adobe Granite UI Clientlibs Bundle
I am still exploring rest of the options related to this configuration. We will share an another blog on the same.

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 .

Thursday, June 22, 2017

ClientLibs in AEM 6.3 - Part1


Hello Everyone,

Clientlibs is one of my favorite concepts of AEM and frequently asked in interviews.There is a lot of information available on internet regarding same. Lets discuss some of the concept related to clientlibs in this blog...

Below are the questions which hits your mind when you think about clientlibs:
  • What are Client-Side Libraries?
  • Why Client-Side Libraries?
  • Feature or Properties of Clientlibs
  • Tips and Tricks over the concept of Clientlibs

Let's explore the answers for all above ...

What are Client-Side Libraries?

➤ Modern websites rely heavily on client-side processing driven by complex JavaScript and CSS code. Organizing and optimizing the serving of this code can be a complicated issue.

To deal with this issue, AEM provides the concept of Client-Side Library Folder which allows you to store client side code in the repository, organize it into categories and decide when and how each category code is served to the client.

Client side libraries play a very crucial role to provide rich functionality to end user. Clientlibs  is used to manage these libraries in AEM.

Why Client-Side Libraries?

Client-Side Libraries include JS and CSS files. Below is the traditional way of using these on any web page:

<head>
<link rel="stylesheet"href="/etc/clientlibs/aem-developer/css/test.css">
<script type="text/javascript"src="/etc/clientlibs/aem-developer/js/test1.js"></script>
<script type="text/javascript" src="/etc/clientlibs/aem-developer/js/test.js"></script>
</head>

In the above code, there will be separate network call for each js and css file.

But think, if hundreds of CSS and JS files present in website, then each file will have a network call due to which overall performance will be reduced as load time of a web page will increase gradually.


No. of Request  Page load Time

So AEM came up with a better approach. Only two calls will be there for single clientlibs, one for js and another for CSS.

Irrespective of number of CSS file present, only single CSS call will be there and all css file will be embedded in same call and same applicable for JS file as well.

How to Create Client-Side Library Folder

Steps to follow:
1.Go to any folder where you want to locate a client library Folder.Create a Node here of type cq:clientLibraryFolder.
2.To specify the categories ,add the property in the clientLibraryFolder like this:
  • Name : categories     
  • Type : String[]    
  • Value : category_name
3.Add source files(css and js files) to the categories.You can organise these files in subfolders as well.
4.Select the clientLibraryFolder, and create the following files:
  • js.txt: Use this file to generate java script file.
  • css.txt: Use this file to generate css file.
5.In the above files,add the base to identify the root of the source files.
#base=[root]
Replace [root] with the path of the folder that contains the source files,relative to the txt files.

If all the source files are in the same folders of the txt files.Use this
#base=.

If all the source files are under a specific folder i.e. mobile 
#base=mobile

How AEM manage the ClientLibs?

There are two ways to include client-side libraries in your page but it depends on what we are using (JSP or HTL), But nowadays HTL is very popular in AEM.

In HTL (Sightly): 

<sly data-sly-use.clientLib="${'/libs/granite/sightly/templates/clientlib.html'}"/>
 <sly data-sly-call="${clientLib.all @ categories='apps.aem-learning'}"/>

Note: In HTL,client libraries are loaded through a helper template(/libs/granite/sightly/templates/clientlib.html) provided by AEM.

This helper template expects a categories option for referencing the desired client libraries.That option can be either an array of string values, or a string containing a comma separated values list.

Note: Here keyword “all” stands for all the JS and CSS files.If you want to call js and CSS specifically, replace all keyword with “CSS” or “JS”.

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

Use below if you want to use CSS specifically, 
<ui:includeClientLib css="apps.aem-learning"/>

Use below  if you want to use JS specifically,

<ui:includeClientLib js="apps.aem-learning"/>

The generated HTML page contains the following code:

<link rel="stylesheet" href=”/etc/clientlibs/aem-developer.css" type="text/css"></link>
<script type="text/javascript" src="/etc/clientlibs/aem-developer.js"></script>

Note: <cq:includeClientLib> which in the past was commonly used to include client libraries, has been deprecated since AEM 5.6.<ui:includeClientLib> should be used instead as detailed above.

Feature or Properties of ClientLibs

  • Categories: This property uniquely identifies the Clientlibs and a Clientlibs can be included in a page using categories.The categories property being multi-valued,allows a library folder to be the part of more than one category.
Note: It is advisable to preface the category value by ‘apps’ or ‘etc’ to specify the location of Clientlibs.

  • Dependencies: There is a list of other client-side libraries on which the library folder depends.

To identify dependencies, add a property to your cq:ClientLibraryFolder node with the following attributes:

dependencies.PNG
Fig - dependencies property in clientlib folder

  • Name: dependencies
  • Type: String[]
  • Values: The value of the categories property of the cq:ClientLibraryFolder node that the current library folder depends on.
Example: If clientlib  A is having B as a dependency.Then 4 network calls will exist.First B will get executed because A tries to resolve all its dependencies and then A  executes itself.
<link rel="stylesheet" href=”/etc/clientlibs/sgaem/B.css" type="text/css">
<script type="text/javascript" src="/etc/clientlibs/sgaem/B.js"></script>
<link rel="stylesheet" href=”/etc/clientlibs/sgaem/A.css" type="text/css">
<script type="text/javascript" src="/etc/clientlibs/sgaem/A.js"></script>

Note: Dependencies property is transitive – if Clientlib A depends on B and B depends on C, then all clientlibs will be included in the page in the order of C>B>A.

  • Embed: It is used to embed code from other libraries. Use the categories property to identify the client library folder to embed. To embed the library, add a property to the embedding cq:ClientLibraryFolder node, using the following property attributes:

embed.PNG
Fig- embed property in clientlib folder
  • Name: embed
  • Type: String[]
  • Value: The value of the categories property of the cq:ClientLibraryFolder node that the current library folder embed upon.
Example: If clientlibs B is embed with A ,then only 2  network calls will exist. B will be concatenated with A's  content in itself and only A will be seen in the network call.

Note: Name of final JS or CSS  file will be same as the parent client-library. Here A is the parent client-library folder.
<link rel="stylesheet" href=”/etc/clientlibs/sgaem/A.css" type="text/css">
<script type="text/javascript" src="/etc/clientlibs/sgaem/A.js"></script>

This property reduces a large number of network calls for clientlibs.


Note: Embed property is NOT transitive – If Clientlib A embed B and B embed C, then only A and B will be included in the page,but C won't. In order to include Clientlib C, it must be added to the embed property of A as well.



Tips and Tricks over the concept of clientlibs


Let's troubleshoot What happens when:

Clientlibs A is dependent on B,B is dependent on C

ClinetlibExample1 (1).jpg
Fig- Example of nested dependencies property

CSS Calls:
<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/C.css" type="text/css">
<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/B.css" type="text/css">
<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/A.css" type="text/css">

JS Calls:

<script type="text/javascript" src="/etc/clientlibs/aem-developer/C.js"></script>
<script type="text/javascript" src="/etc/clientlibs/aem-developer/B.js"></script>
<script type="text/javascript" src="/etc/clientlibs/aem-developer/A.js"></script>

A category tries to solve its dependency and B also does the same,that’s why C is being called very first and after that B and A.

Clientlibs A is embed on B,B is embed on C.

ClinetlibExample2 (1).jpg
Fig- Example of nested embed property

Embed doesn’t provide transitive addition that’s why only A and B is being called.B is embedded in A calls.

<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/A.css" type="text/css">
<script type="text/javascript" src="/etc/clientlibs/aem-developer/A.js"></script>

Clientlibs A is dependent on B,B is dependent on C and C is dependent on A

Note:No clientlibs is getting called as it becomes the condition of infinite loop

Clientlibs A is embed on B,B is embed on A.

Note: It will work same as scenario:2 as B doesn’t consider its embed to be resolved because embed doesn’t have transitive addition.


Clientlibs A is embed on B and dependent on C.

ClinetlibExample5 (1).jpg
Fig- Example of embed with dependencies property

If a clientlibs will have both dependency and embed,then it’s priority will be to resolve dependency at first and then embed.

NO. of CSS calls:

<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/C.css" type="text/css">
<link rel="stylesheet" href=”/etc/clientlibs/aem-developer/A.css" type="text/css">

NO. of JS Calls:

<script type="text/javascript" src="/etc/clientlibs/aem-developer/C.js"></script>
<script type="text/javascript" src="/etc/clientlibs/aem-developer/A.js"></script>

After all this interesting stuff,clientlibs is not over yet.So stay tune and wait for our next blog.

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 .😊