|Request for Feature Enhancement (RFE) Summary:||Component specific client-library in ui.frontend project and better dependency management for client libraries.|
1. Currently, all the code written in ui.frontend will be bundled as 2 client libraries i.e: clientlib-site and vendors. These client libraries will be loaded in all pages. There is no way to selectively load only certain components OOTB. This leads to sub-optimal lighthouse scores because unused CSS and JS code on page. Hence, there has to be modularity in the clientlibs generated from ui.frontend project. This can be achieved through proper webpack configurations
2. Currently there are two ways to load client libraries
i) At template level: This is recommended because it ensures all CSS wil be loaded at the top (in head) and all JS will be loaded at the bottom. But this gives rise to unused JS and CSS code on page as there is no option to include only those clientlibs which is needed on a particular page.
ii) At component level: This ensures that only required CSS/JS will be loaded. If a particular component is not loaded, corresponding CSS/JS will not load. But, with this approach render blocking CSS and JS code is loaded in body tag which is not recommended.
Hence there needs to be an approach to fix both of this performance issues. If there can be a way to dynamically load client libs (and its dependencies) based on components present on page, this will highly improve page performance.
|Environment Details (AEM version/service pack, any other specifics if applicable):||AEM 6.5.x|
|Screenshot (if applicable):||
Without optimization: Clientlibs loaded at component level.
With optimization: I have used an interceptor to group all CSS in head section and all JS to the bottom of the body tag.
|Code package (if applicable):|
Good feature request.
I ask myself, how this should be implemented. I think that it would need an extension of the maven archetyp (ui.frontend module) to create a dedicated clientlib per component, plus an adapted configuration per component.
From my point of view it's hard to to make this generic, because in the archetype itself it's unclear how many components you are going to have and how they are named. I could imagine a "component creation wizard", which creates all necessary structures in ui.frontend, ui.apps and potentially other locations to implement this.
On the other hand, this can also be implemented easily manually (you don't need work done by Adobe) when you create that all manually (or build a script to support you here). Can you create a feature request at the maven archetype project (https://github.com/adobe/aem-project-archetype) and link this proposal?
Thanks for your reply. I have been successful in achieving below feature myself:
What I am not able to do is, dynamically load vendor dependencies:
Scenario 1: Page 1 loads Clib1 and Clib2. Clib1 needs Jquery and Bootstrap
Scenario 2: Page 2 loads Clib3 and Clib4. Clib3 needs only Jquery
In this case vendor.js will be same. You will be loading Bootstrap in Page 2 also thereby bloating the page.
Thanks for the explanation!
Thanks for proposing the idea. If I understand it correctly the suggestion is majorly for the archetype modularity or is there any expectation from the product side as well?
What is needed from archetype modularity perspective?
Ability to generate modular client libraries from ui.frontend folder.
I am able to achieve this by making changes in webpack config and clientlib config. But it will be good to have this in archetype.
What is needed from product perspective?
In order to reduce the number of js/css calls in HTML, the recommended ways to load client libs is to bundle multiple clientlibs into 1 client (using embed) and load it in template level.
There is a JS/CSS heavy component which is not needed on every page. Ex: shop locator component.
Problem 1: If I load this with embed at template, then this heavy JS/CSS will be unnecessary loaded on pages where it is not needed.
Problem 2: If I load this with at component level, since css/js is render blocking, it goes against the principle of loading css on head and JS at bottom. And if there are multiple such components, it increases the number of CSS and JS.
Hence here is the first expectation from product perspective:
A way (interceptor/transformer?) to collate all component level clientlib inclusion, and pushes the css to head and JS to the bottom of the page while rendering a page.
(Extension of scenario 1) There are multiple JS/CSS heavy components which is not needed on every page.
1. Page 1 has comp1 which has dependency1, dependency2
2. Page 2 has comp2 has dependency1, dependency3
If you use webpack to create vendor packages, it will generate a vendor package consisting of dependency1+dependency2+dependency3.
Problem: If you load vendor clientlib on page1 and page2, you are loading unnecessary dependencies on both pages leading to longer page load time.
Hence the second expectation from product perspective:
A way to identify dependencies of clientlibs and bundle the dependencies dynamically.
Hope this clarifies. Thanks
we had this kind of implementation with another CMS product, where we were loading clientlibs based on component from UI but we used to load those clienlibs(only JS, CSS does not have much impact on performance) as separate request for each/unique component and the reason was -
1. If you combine component clienlibs dynamically and deliver as a single file then you might ending up 1 clientlibs/1 page and thats not good for caching and it is almost hitting publishers.
2. You have to cut off caching for clientlibs in this cash.
3. No hashed or version clientlibs.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.