Table of Contents & Menu
Navigation

The Alpine.js x-defer plugin

Available since Hyvä 1.3.7

The x-defer directive is a Hyvä Alpine.js plugin for deferring Alpine component initialization.
Place `x-defer` on the same element as `x-data`.
Its value determines when the component initializes. Possible values are:

  • intersect
  • interact
  • idle
  • event:eventname

Deferring non-critical component initialization improves page interactivity and reduces main thread blocking time.
Proper use enhances Core Web Vitals scores.

Choose the trigger type based on the component's needs.

What components can be deferred?

Deferred components might miss events if their subscribers aren't active during the event dispatch.
A common issue is components needing customer section data missing the private-content-loaded event.

Workaround: Dispatch the reload-customer-section-data event within the component's `x-init` method.
This re-dispatches `private-content-loaded`, allowing the component to receive it.

For example:

<div
    x-data="{cart: null}"
    x-defer="intersect"
    x-init="$dispatch('reload-customer-section-data')"
    @private-content-loaded="cart = $event.details.data.cart"
>

Values for x-defer

x-defer="intersect"

This common `x-defer` type initializes a component only when it enters the viewport.
If already in the viewport on page load, it initializes immediately.

<div x-data x-defer="intersect">
    <span x-text="`This component is initialized when it enters the viewport.`"></span>
</div>

x-defer="interact"

This initializes a component upon any user interaction (e.g., touchstart, mouseover, wheel, scroll, or keydown).

<div x-data x-defer="interact">
    <span x-text="`This component is initialized on user interaction.`"></span>
</div>

x-defer="idle"

Initializes the component when the browser is idle, using window.requestIdleCallback.
A configurable timeout ensures initialization even if the browser doesn't trigger the callback.
Configure this timeout at Hyvä Themes > General > Deferred Alpine.js Components > Defer until idle timeout
Default timeout: 4000ms.

<div x-data x-defer="idle">
    <span x-text="`This component is initialized when the browser is idle or after 4s.`"></span>
</div>

x-defer="event:eventname

Use the `event:` prefix to defer component initialization until a specified event.
The event is observed on the window object.

<div x-data x-defer="event:toggle-cart">
    <span x-text="`This component is initialized when the toggle-cart event is dispatched.`"></span>
</div>

Configurable component defer rules

The `x-defer` attribute can be added directly to .phtml templates or injected via JavaScript.
Rules can be configured via layout XML or backend system configuration.

Injecting x-defer rules with layout XML

Configure defer rules in layout XML by adding items to the `deferred_components` array argument of the `alpine-defer-rules` block.

<referenceBlock name="alpine-defer-rules">
  <arguments>
    <argument name="deferred_components" xsi:type="array">
      <item name=".product-slider > div > section[x-data]" xsi:type="string">intersect</item>
    </argument>
  </arguments>
</referenceBlock>

Item keys act as `document.querySelectorAll` selectors; values become the `x-defer` attribute value.
Currently, no default rules are configured in layout XML.

Injecting x-defer rules through backend configuration

To easily improve Core Web Vitals for existing custom themes, useful defer rules are automatically injected into components based on configurable selectors.
Configure these at Hyvä Themes > General > Deferred Alpine.js Components > Defer components

The default `x-defer` configuration includes these selectors:

  • .product-slider section[x-data]
    Defers product sliders (e.g., on the homepage).
  • .product-info [x-data]
    Matches all components within product listing items.
  • #filters-content [x-data]
    Matches layered navigation filter components.
  • #review_form
    Matches the product review form on product detail pages.
  • section[x-data^=initRecentlyViewedProductsComponent]
    Matches the recently viewed products widget.
  • div[x-data^=initBundleOptions]
    Defers bundled product option components.
  • #product_addtocart_form [x-data]
    Defers swatches and options on product detail pages.
  • #notice-cookie-block
    Matches the cookie notice.

Tip

Since Hyvä 1.3.7, the `hyva-themes/magento2-default-theme` already includes `x-defer` attributes directly in .phtml templates.
Thus, the default `x-defer` injection rules are redundant for themes based on 1.3.7 or newer; they only benefit older releases.

For new custom themes based on default-theme 1.3.7+, you can remove the default backend `x-defer` rules.
This can further reduce TBT.

Disabling defer rules injection

To completely disable `x-defer` injection in a theme, remove the `alpine-defer-rules` block via layout XML.

<referenceBlock name="alpine-defer-rules" remove="true"/>