Defer dialog content loading until user interaction
Guard expensive Liquid operations inside dialogs, drawers, and expandable components with conditional parameters to prevent loading content on every page request when the component isn't visible.
Dialogs and drawers that load content on every page request waste server resources even when users never open them. Common expensive operations include collection queries (collections.all.products), variant iteration (product.variants), and metafield access. All of these execute during initial page render if not guarded.
The predictive search dialog pattern from Horizon v2.1.4 demonstrates the impact: removing an unguarded settings.empty_state_collection.products | default: collections.all.products assignment saved 400 ms on every page load by preventing evaluation of product.available, product.price_max, and other properties that must assess all variants.
For stores with high-variant products (1,000 or more variants per product), accessing collections.all without a limit can add 1 to 3 or more seconds to TTFB because the server loads full product data for potentially hundreds of products.
Anchor to Add conditional loading parametersAdd conditional loading parameters
Create a parameter that controls whether the expensive content loads:
snippets/search-modal-content.liquid
Anchor to Load content on user interactionLoad content on user interaction
On initial render, include the dialog shell with load_content: false. When the user opens the dialog, fetch a dedicated section that renders the snippet with load_content: true through the Section Rendering API:
sections/search-modal-loaded.liquid
sections/header.liquid
Anchor to Fetch only the items you renderFetch only the items you render
Even with conditional loading, keep the query small. For collection.products, a for loop's limit already reduces the fetch, so a fixed-size list doesn't need a {% paginate %} wrapper, and adding one couples the section to the page URL parameter. Other arrays, such as blog.articles, need {% paginate %} to limit the fetch. See Limit how many items a Liquid array fetches for which arrays behave which way.
Anchor to ExamplesExamples
Anchor to Predictive search dialog (Horizon v2.1.4 pattern)Predictive search dialog (Horizon v2. 1. 4 pattern)
Before optimization:
Problems:
- Loads
collections.all.productson every page. - No
limiton the loop, so it fetches the full default page size of 50 products. - Evaluates
product.availableandproduct.price_maxfor all variants. - Adds 400 ms or more to TTFB on stores with high-variant products.
After optimization:
Benefits:
- No collection query on the initial page load.
- The
limit: 4passed to the products list caps the loop, which reduces the fetch to 4 products instead of the default 50. - 400 ms faster TTFB on every page.
- Content loads on the first dialog open using JavaScript.
Anchor to Cart drawer with recommendationsCart drawer with recommendations
The recommendations object is only populated when the section is rendered through the Product Recommendations API endpoint (/recommendations/products?section_id=...&product_id=...), not through a generic Section Rendering API request. Render the drawer shell on the initial page load without recommendations, then fetch the recommendations section from the correct endpoint when the drawer opens.
sections/cart-drawer-recommendations.liquid
Usage:
Anchor to Accordion and tabs with expensive contentAccordion and tabs with expensive content
snippets/product-details-tab.liquid
Anchor to Size guide dialog with variant dataSize guide dialog with variant data
snippets/size-guide-modal.liquid
Anchor to TestingTesting
- Measure TTFB: Compare before and after with dialog content guarded. Should improve by 100 to 400 ms or more depending on query complexity.
- Theme Inspector: Use the sandwich view to verify that expensive operations, such as collection queries and variant iteration, no longer execute on the initial page load.
- Network tab: Verify that dialog content loads through the Section Rendering API when the user opens the dialog.
- Test with realistic data: Use products with 100 or more variants and collections with 50 or more products to see the real impact.
Anchor to ReferencesReferences
paginatetagiftagcollections.allproduct.variantsrecommendations.products- Use the Section Rendering API for dynamic updates
- Limit pagination depth
- Avoid over-fetching product variants
- Avoid deeply nested Liquid loops