I inherited code for an application that uses resourceResolver instances quite liberally. Notably this code has a custom tag library for generating anchor tags. When called it takes the link and checks to see if it’s a page in the AEM using a resourceResolver. In the case of the navigation or footer it does this hundreds of times in total, per server hit.
We’re struggling with performance issues and I set JProfiler against the application and that’s the only thing that jumps out. Moderately high average CPU time making the getResourceResolver call.
So I’m wondering what the overall overhead of this method is in case what’s happening is slowdown caused by so many calls to this method.
@prestonModOp In the use case like this where you need to check each url and rewrite it, using sling rewriter pipeline would be better. Sling has the possibility to rewrite the output/generated markup of a page via a pipelining feature and it is activated in AEM by default (used for the AEM-builtin link checker and link rewriting features). You would have to create a new transformer-type and add it to the rewrite configuration.
Opening a ResourceResolver is normally opening a JCR session. Which comes with some overhead.
Some time back I profiled a publish instance in load tests and found that eliminating a single filter, which opened and closed a JCR session (and doing some work in between) increased the number of requests my publish was able to handle by ~ 5%.
So if you do that lots of times during the rendering of a page, it will negatively impact the performance of the page rendering.
We are also using link scanning to identify internal links with specific format using subservice session via sling output rewrite pipeline. we did not see any performance issues, even though we have a header and footer with internal links.
I would suggest using sling rewriter pipeline which allows you to restrict link scanning based on path, link extension, attribute, tags etc. This will help to improve performance.
Whenever we use ResourceResolver, it’s a 100% chance that you will open a JCR session. Hence, we should call “close()” on every resolver once the job is done.
API calls which open a JCR resource: SlingRepository.loginAdminstrative() , DEPRECATED! SlingRepository.loginService()
API calls, which create a Sling ResourceResolver: ResourceResolverFactory.getAdministrativeResourceResolver(), DEPRECATED! ResourceResolverFactory.getResourceResolver() ResourceResolverFactory.getServiceResourceResolver()
Also, when we have already opened a ResourceResolver, adapting it to a Session.class will just expose the internally used JCR session; it will not create a new Session for it. Therefore we do not need to close the session.