Fix Adobe Experience Manager LCP Issues | OpsBlu Docs

Fix Adobe Experience Manager LCP Issues

Improve AEM LCP by optimizing clientlibs loading, configuring Dispatcher caching, and using Dynamic Media for responsive images.

General Guide: See Global LCP Guide for universal concepts and fixes.

AEM-Specific LCP Causes

1. Heavy Client Libraries

Blocking clientlibs delay page render:

<!-- Problem: Blocking CSS in head -->
<sly data-sly-call="${clientlib.all @ categories='mysite.all'}"/>

2. Unoptimized DAM Assets

Large images from DAM without optimization:

<!-- Problem: Full-size DAM image -->
<img src="/content/dam/mysite/hero.jpg"/>

3. Dispatcher Cache Misses

Cold cache or frequent invalidation:

MISS → Origin fetch → Slow response

4. Component Render Time

Complex HTL logic or slow Sling Models:

// Slow: Heavy query in model
public List<Page> getRelatedPages() {
    return pageManager.search(new Query()); // Expensive!
}

AEM-Specific Fixes

Fix 1: Optimize Client Library Loading

Split critical and non-critical CSS:

<!-- Critical CSS inline -->
<style data-sly-use.critical="${'com.mysite.CriticalCSSModel'}">
    ${critical.css @ context='unsafe'}
</style>

<!-- Non-critical async -->
<link rel="preload" as="style"
      href="/etc.clientlibs/mysite/clientlibs/site.css"

Use async for JavaScript:

<!-- clientlib definition -->
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:ClientLibraryFolder"
    categories="[mysite.scripts]"
    jsProcessor="[default:none,min:none]"
    async="{Boolean}true"/>

Fix 2: Use Dynamic Media or Asset Compute

Enable Dynamic Media for responsive images:

<sly data-sly-use.dm="${'com.adobe.cq.dam.dm.api.DMImageProfileService'}">
    <img src="${asset.path @ selectors='width_800', extension='webp'}"
         srcset="${asset.path @ selectors='width_400'}?wid=400 400w,
                 ${asset.path @ selectors='width_800'}?wid=800 800w"
         sizes="(max-width: 600px) 400px, 800px"
         loading="lazy"
         width="800"
         height="600"
         alt="${asset.title}">
</sly>

Or use Asset Compute:

<!-- Web-optimized delivery -->
<img src="${asset.path}.transform/width-800/format-webp/quality-85.webp"/>

Fix 3: Optimize Dispatcher Caching

Configure aggressive caching:

dispatcher.any

/cache {
    /rules {
        /0000 { /glob "*" /type "allow" }
    }

    /headers {
        "Cache-Control"
        "Expires"
    }

    /gracePeriod "300" # Serve stale while revalidating
}

Add preload hints:

<sly data-sly-use.page="${'com.mysite.core.models.PageModel'}">
    <link rel="preload"
          href="${page.heroImage}"
          as="image"
          type="image/webp">
</sly>

Fix 4: Optimize Sling Models

Use lazy loading and caching:

@Model(adaptables = SlingHttpServletRequest.class,
       cache = true)
public class PageModel {

    private List<Page> relatedPages;

    // Lazy initialization
    public List<Page> getRelatedPages() {
        if (relatedPages == null) {
            relatedPages = computeRelatedPages();
        }
        return relatedPages;
    }

    @PostConstruct
    protected void init() {
        // Only initialize critical data here
    }
}

Fix 5: Use Core Components

Core Components are optimized for performance:

<!-- Use Core Image Component -->
<div data-sly-resource="${'image' @ resourceType='core/wcm/components/image/v3/image'}">
</div>

Core Image automatically:

  • Generates responsive srcset
  • Lazy loads below-fold images
  • Applies web-optimized renditions

Fix 6: Preconnect to External Resources

Add preconnect for third-party resources:

<sly data-sly-test="${page.hasAnalytics}">
    <link rel="preconnect" href="https://www.googletagmanager.com">
    <link rel="preconnect" href="https://www.google-analytics.com">
    <link rel="dns-prefetch" href="https://www.googletagmanager.com">
</sly>

Monitoring LCP

Track with Web Vitals:

// Client library: mysite.webvitals
import {onLCP} from 'web-vitals';

onLCP(function(metric) {
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
        'event': 'web_vitals',
        'vital_name': 'LCP',
        'vital_value': metric.value,
        'vital_rating': metric.rating,
        'vital_element': metric.entries[0]?.element?.tagName
    });
});

LCP Targets

Rating LCP Value
Good ≤ 2.5s
Needs Improvement 2.5s - 4.0s
Poor > 4.0s

Next Steps