Performance starts with how you load data onto a page. Hydrogen gives you the ability to fetch data server-side, but if it’s not done efficiently, then your store’s [Time To First Byte](https://web.dev/articles/ttfb) (TTFB) can suffer. TTFB is the time it takes for your website to start loading from when it's requested, until it first starts to show on your screen.

To better understand these requests that fetch data, Hydrogen ships with a tool called the [Subrequest Profiler](/docs/storefronts/headless/hydrogen/debugging/subrequest-profiler). This should be your first stop in diagnosing performance issues.

This document offers a set of best practices for our Hydrogen merchants to support efficient data loading, improving the speed of storefronts and customer experience.

## Fetch data in parallel

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/eliminate-waterfalls-2x-6567f6e8f95c6dd047b48c3b6f8439bf0a86537eec0b49bfce2899e2504a6d98.png" class="lazyload themed-image" data-alt-src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/eliminate-waterfalls-2x-dark-bae6906b6ef045eae6feca7e3bed8f040c98a1eb68e974254cb677b47a55a24d.png" alt="Diagram of two data loading strategies, waterfall vs. parallel" width="1760" height="680"></figure>

It's common for pages to fetch data from more than one source. For example, your product page might fetch some product information from Shopify and additional content from a third party service such as a CMS.

When awaiting this data it’s easy to end up with a "request waterfall", where each request is made one after another, causing an often avoidable delay. Where possible, it's faster to execute these requests simultaneously.

This can be achieved inside your data loaders using `Promise.all`:

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENTexport async function loader({params, context}) {
  const {handle} = params;
  const {storefront, thirdPartyContent} = context;

  // Do this
  const [product, thirdPartyContent] = await Promise.all([
    // Both queries execute in parallel
    storefront.query(PRODUCT_QUERY, variables: {handle}),
    thirdPartyContent(),
  ]);

  // Not this
  const product = await storefront.query(PRODUCT_QUERY, variables: {handle});
  const thirdPartyContent = await thirdPartyContent(); // Starts after product query finishes
}
END_RAW_MD_CONTENT</script>

</div>
</p>


As a general rule, only critical data should be prioritized and awaited. For example, product information.

## Prioritize critical data

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/prioritize-data-2x-8a800603b29927653de8de3fffb433cd6cdfcd27887582849ddce716a0f206cc.png" class="lazyload themed-image" data-alt-src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/prioritize-data-2x-dark-62da9b284abe47c0c5e68a98c99ce3875c14f6e37af280018823cd751ef67482.png" alt="Diagram of prioritizing critical data" width="1760" height="792"></figure>

The more data you need to start rendering a page, the longer your TTFB will be. A longer TTFB delays the page load, which negatively affects the user experience and potentially increases bounce rates.

Fortunately, with Hydrogen you can prioritize critical data and stream in any non-critical data later, which enables you to minimize your TTFB. Critical data is anything that you need before rendering the page, such as product information. Non-critical data is anything that can load after the page renders, such as reviews, or anything below the fold.

Defer non-critical data and stream the response so that the page can begin to render as soon as critical data is retrieved.

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENTexport async function loader({params, context}) {
  const {handle} = params;
  const {storefront, fetchReviews} = context;

  // Do this
  const reviews = fetchReviews(handle); // Non-critical data can render whenever it finishes (important to make sure these are initiated before any awaited requests)
  const product = await storefront.query(PRODUCT_QUERY); // Page render awaits critical data
  return defer({product, reviews});

  // Not this
  const reviews = await fetchReviews(handle);
  const product = await storefront.query(PRODUCT_QUERY); // The critical data is delayed until after reviews finish loading!
  return json({product, reviews});
}

END_RAW_MD_CONTENT</script>

</div>
</p>


In order to render streamed data, you need to use `<Suspense>` from React and `<Await>` from Remix.

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="jsx">
RAW_MD_CONTENTexport default function Product() {
  const { product, reviews } = useLoaderData();
  return (
    <>
      {/* Critical product data renders immediately */}
      <ProductDetails data={product} />
      {/* Non-critical review data displays fallback content until the data streams in */}
      <Suspense fallback={<ReviewsSkeleton />}>
        <Await resolve={reviews}>
          {(reviews) => <ProductReviews data={reviews} />}
        </Await>
      </Suspense>
    </>
  );
}
END_RAW_MD_CONTENT</script>

</div>
</p>


## Optimize the loading sequence

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/optimize-loading-2x-ffe8d9866a08b32d99095e848e5685eeef53a92a436a7d9259b28a2e762a0e3e.png" class="lazyload themed-image" data-alt-src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/optimize-loading-2x-dark-99969ce21b584baee3654aa674b3a881034faf2f01d36b95b7c96e7a32953043.png" alt="Diagram of an optimized loading sequence" width="1760" height="906"></figure>

The order of your requests in the loader matters. By initiating deferred (streamed) requests first, you can prevent them being blocked by critical (`await`ed) data. It might seem counterintuitive to start loading non-critical data first, but this ensures that all data loads in parallel.

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENTexport async function loader({params, context}) {
  const {handle} = params;
  const {storefront, fetchReviews} = context;

  // Do this
  const reviews = fetchReviews(handle) // Loads in parallel with the product query
  .catch((error) => {
    // Log any errors, but don't throw them, so that the page can still render
    console.error(error);
    return null;
  });
  const product = await storefront.query(PRODUCT_QUERY);
  return defer({product, reviews});

  // Not this
  const product = await storefront.query(PRODUCT_QUERY);
  const reviews = fetchReviews(handle); // Blocked by the product query
  return defer({product, reviews});
}
END_RAW_MD_CONTENT</script>

</div>
</p>


## Eliminate data dependencies

It’s important to keep in mind that the way third party data is modeled can have an impact on performance. Try to organize it in a way that allows you to perform multiple queries at the same time instead of one after the other. Take the following example where it’s common to store and lookup data by product ID.

By using the product ID as the key, your product page first needs to look up the product ID from Shopify before it can fetch any information. This creates a [request waterfall](#fetch-data-in-parallel).

```js
// Storing data like this...
{
  [productId]: {
    some: "content..."
  }
}

// ...creates a waterfall because your second query has to wait on the product ID
const { product } = await storefront.query(PRODUCT_QUERY, variables: {handle});
const thirdPartyData = await 3PClient.query(3P_PRODUCT_QUERY, { productId: product.id });
```

In contrast, by storing the data by the product handle, you can fetch all data in parallel:

```js
// Storing data like this...
{
  [productHandle]: {
    some: "content..."
  }
}

// ...allows you to fetch all data at once (faster!)
const [{ product }, thirdPartyData] = await Promise.all([
  storefront.query(PRODUCT_QUERY, variables: {handle}),
  3PClient.query(3P_PRODUCT_QUERY, { handle }),
]);
```

## Separate critical and non-critical queries

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/split-queries-2x-f347682a1342e6e4ababba3ba38b1b9b815cf78bb73a8c632d55eb2bc0a380b5.png" class="lazyload themed-image" data-alt-src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/split-queries-2x-dark-d667256c2c07ccb20b370794e21f876e7963c6fe947375869b4f10525619be2a.png" alt="Diagram of splitting queries" width="1760" height="974"></figure>

Larger queries are slower to execute. If a single query contains both critical and non-critical data, consider splitting it into multiple queries so you can defer the non-critical content.

A good example is found on the product page. A product query often fetches all of the product’s variants up front, which can be a lot of data. By splitting it into two queries and deferring all of the possible variants, the product page can render more quickly, with the variant data streaming in after the initial page load. [See Hydrogen’s Skeleton template for reference](https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/routes/products.%24handle.tsx#L416-L480).

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENTexport async function loader({params, context}) {
  const {handle} = params;
  const {storefront} = context;

  // Do this
  const variants = storefront.query(VARIANTS_QUERY, variables: {handle}); // Bigger, slower query
  const product = await storefront.query(PRODUCT_QUERY, variables: {handle}); // Smaller, faster query
  return defer({product, variants});

  // Not this
  const product = await storefront.query(PRODUCT_AND_VARIANTS_QUERY, variables: {handle}); // One big slow query
  return json({product});
}
END_RAW_MD_CONTENT</script>

</div>
</p>


Query splitting also provides more fine-grained control over your caching. Each query can use the best caching strategy for its data type.

## Do not over-fetch

Fetching data that isn’t used (aka over-fetching) increases response times and causes unnecessary processing.

The great part about GraphQL is you have the ability to request only the data you need for your page, so make sure that every field in your query is being used on your page — and if it’s not, get rid of it!

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENTconst CollectionCard = (collection) => {
  return (
    <div>
      <Image data={collection.image} />
      <h2>{collection.title}</h2>
    </div>
  );
};

// Do this
const COLLECTIONS = `#graphql
  query FeaturedCollections {
    collections(first:10) {
      nodes { # Only fetch the fields required to render the collection card
        id
        title
        image {
          id
          url
          altText
          width
        }
      }
    }
  }
`;

// Not this
const COLLECTIONS = `#graphql
  query FeaturedCollections {
    collections(first:3) {
      nodes {
        id
        title
        image {
          id
          url
          altText
          width
        }
        products(first:250) { # Collection card doesn't use products, this can be removed
          ...Product
        }
      }
    }
  }
`;
END_RAW_MD_CONTENT</script>

</div>
</p>


Review your loaders to ensure that you’re only requesting resources that are actually required and your GraphQL queries only contain fields that are used.

## Leverage caching

<figure class="figure"><img src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/leverage-caching-2x-71c8b9d27038ba6faa793d2b002809963e3250465bf256c71ce2ffbd119b8231.png" class="lazyload themed-image" data-alt-src="https://cdn.shopify.com/shopifycloud/shopify_dev/assets/custom-storefronts/hydrogen/performance/leverage-caching-2x-dark-894e9fb9aaca32fc46a25214a60e0127252ef6746ac006f95d498e65819e04d6.png" alt="Diagram of caching vs. no caching" width="1760" height="962"></figure>

Fetching data over the network takes time. You can eliminate this delay for future visitors by caching the response of each subrequest.

Think of caching as a last line of defense. After you have an efficient data loading strategy in place, supercharge the storefront by caching your subrequests. For data that changes regularly, adopt short-term caching. For stable data, implement longer-term caching strategies.

<aside class="note note-caution">
<p>Never cache personalized content, like carts. This can lead to a scenario where one user's data is mistakenly shown to another.</p>
</aside>

The Storefront API client built into Hydrogen includes the following [caching strategies](/docs/storefronts/headless/hydrogen/caching#caching-strategies):

<p>
<div class="react-code-block" data-preset="basic">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar basic-codeblock"></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>


<script type="text/plain" data-language="js">
RAW_MD_CONTENT// Default caching strategy (suitable for most queries)
storefront.query(QUERY);

// No cache (e.g. personalized data)
storefront.query(QUERY, {cache: storefront.CacheNone()});

// Short caching strategy (e.g. product price)
storefront.query(QUERY, {cache: storefront.CacheShort()});

// Long caching strategy (e.g. shop name)
storefront.query(QUERY, {cache: storefront.CacheLong()});

// Custom caching strategy (e.g. third party CMS data)
storefront.query(QUERY, {cache: storefront.CacheCustom()});
END_RAW_MD_CONTENT</script>

</div>
</p>


For third party data, use Hydrogen’s built-in [`withCache`](/docs/storefronts/headless/hydrogen/caching/third-party#hydrogen-s-built-in-withcache-utility) utility.

<aside class="note note-information">
<p>You can manually bust the cache by triggering an Oxygen redeploy.</p>
</aside>