Shopify 水素と酸素: エッジでのパフォーマンスの高い React ストアフロントの構築
Hydrogen は、Remix: Storefront API GraphQL に基づく公式 Shopify React フレームワークです。 プリミティブ カート コンポーネント、Oxygen での SSR ストリーミング (エッジ Cloudflare ワーカー)、最適化 キャッシュ戦略と従来の Liquid テーマから移行する方法について説明します。
水素: Shopify のコマース フレームワーク
Shopify 水素 ストアフロントを構築するための公式 React フレームワークです ヘッドレスShopify。現在のバージョン (Hydrogen 2.x) では、以下に基づいて構築されています。 リミックス、 アーキテクチャのネイティブ Web API とサーバー アクションを活用する React メタフレームワーク 徐々に改善されました。
酸素 Shopify の Hydrogen プロジェクト用のグローバル ホスティング ランタイムです。 に基づいて Cloudflare ワーカー (V8 Isolates)、サーバー側コードを実行します エッジ — エンドユーザーに最も近いデータセンター内。結果は1つです 世界全体で 30 ~ 80 ミリ秒の TTFB (最初のバイトまでの時間)、サーバーでは達成不可能 伝統的な集中型。
水素プロジェクトの立ち上げ
# Crea un nuovo progetto Hydrogen
npm create @shopify/hydrogen@latest my-store
# Rispondi alle domande:
# - Store domain: mystore.myshopify.com
# - Storefront API token: [da Shopify Admin > Apps > Develop apps]
# - Language: TypeScript
# - CSS: Tailwind CSS
cd my-store
npm run dev
# Apre su http://localhost:3000
Hydrogen プロジェクトの構造は Remix に基づいており、古典的なプロジェクトと非常によく似ています。 ファイルベースのルーティング:
app/
├── components/ # Componenti UI riutilizzabili
│ ├── Cart.tsx # Componente carrello
│ ├── ProductCard.tsx # Card prodotto
│ └── Header.tsx # Header con mini-cart
├── routes/ # File-based routing Remix
│ ├── _index.tsx # Homepage (/)
│ ├── products.$handle.tsx # Pagina prodotto (/products/[handle])
│ ├── collections.$handle.tsx # Collection (/collections/[handle])
│ └── cart.tsx # Pagina carrello (/cart)
├── lib/
│ ├── fragments.ts # GraphQL fragments riutilizzabili
│ └── utils.ts # Utility functions
├── root.tsx # Root layout
└── entry.server.tsx # Server-side entry point
ストアフロント API: 水素コア
Hydrogen は、以下を介して Shopify に接続します。 ストアフロント API GraphQL。あらゆる操作 commerce は GraphQL クエリまたはミューテーションです。 Hydrogen は、事前構成されたクライアントを提供します。
// app/routes/products.$handle.tsx
// Pagina dettaglio prodotto
import {json} from '@shopify/remix-oxygen';
import {useLoaderData} from '@remix-run/react';
import {Image, Money} from '@shopify/hydrogen';
import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
const PRODUCT_QUERY = `#graphql
query Product($handle: String!, $selectedOptions: [SelectedOptionInput!]!) {
product(handle: $handle) {
id
title
descriptionHtml
vendor
selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions) {
id
availableForSale
selectedOptions { name value }
price { amount currencyCode }
compareAtPrice { amount currencyCode }
image { url altText width height }
}
options {
name
values
}
variants(first: 100) {
nodes {
id
availableForSale
selectedOptions { name value }
price { amount currencyCode }
}
}
}
}
`;
export async function loader({ params, context, request }: LoaderFunctionArgs) {
const { handle } = params;
const { storefront } = context;
// Leggi le opzioni selezionate dalla URL (?color=red&size=M)
const searchParams = new URL(request.url).searchParams;
const selectedOptions = [];
for (const [name, value] of searchParams) {
selectedOptions.push({ name, value });
}
const { product } = await storefront.query(PRODUCT_QUERY, {
variables: { handle, selectedOptions },
cache: storefront.CacheShort(), // cache di 1 minuto su Oxygen
});
if (!product) throw new Response('Not Found', { status: 404 });
return json({ product });
}
export default function Product() {
const { product } = useLoaderData<typeof loader>();
const { selectedVariant } = product;
return (
<div className="product">
{selectedVariant?.image && (
<Image
data={selectedVariant.image}
className="product-image"
sizes="(min-width: 768px) 50vw, 100vw"
/>
)}
<h1>{product.title}</h1>
{selectedVariant && (
<Money data={selectedVariant.price} />
)}
<AddToCartButton variant={selectedVariant} />
</div>
);
}
Cart API: 水素でカートを管理
水素は、 ShopifyのカートAPI (に基づく GraphQL の変異)。このフレームワークには、即時更新のための楽観的な UI システムが含まれています。
// Aggiungere un prodotto al carrello
const ADD_TO_CART_MUTATION = `#graphql
mutation cartLinesAdd($cartId: ID!, $lines: [CartLineInput!]!) {
cartLinesAdd(cartId: $cartId, lines: $lines) {
cart {
id
totalQuantity
cost {
totalAmount { amount currencyCode }
}
lines(first: 100) {
nodes {
id
quantity
merchandise {
... on ProductVariant {
id
title
product { title }
price { amount currencyCode }
image { url altText }
}
}
}
}
}
}
}
`;
// Componente AddToCartButton con Fetcher di Remix
import { useFetcher } from '@remix-run/react';
function AddToCartButton({ variant }: { variant: ProductVariant }) {
const fetcher = useFetcher();
const isAdding = fetcher.state !== 'idle';
return (
<fetcher.Form method="POST" action="/cart">
<input type="hidden" name="intent" value="add" />
<input type="hidden" name="variantId" value={variant.id} />
<button
type="submit"
disabled={!variant.availableForSale || isAdding}
className="add-to-cart-btn"
>
{isAdding ? 'Aggiunta...' : 'Aggiungi al Carrello'}
</button>
</fetcher.Form>
);
}
Oxygen でのキャッシュ: パフォーマンスの鍵
Oxygen は、Cloudflare Workers エッジで Hydrogen コードを実行します。キャッシュは次の方法で管理されます。 CloudflareのネイティブAPIとHydrogenヘルパー:
// Strategie di cache disponibili in Hydrogen
// Definiamo cache personalizzate per tipo di contenuto
// Cache lunga per pagine prodotto (aggiornamento raro)
export async function loader({ context }: LoaderFunctionArgs) {
const { storefront } = context;
const data = await storefront.query(PRODUCTS_QUERY, {
cache: storefront.CacheLong(), // cache di 1 ora
});
return json(data, {
headers: {
'Cache-Control': 'public, max-age=3600, stale-while-revalidate=86400',
},
});
}
// Cache breve per dati variabili (inventory, prezzi)
const inventoryData = await storefront.query(INVENTORY_QUERY, {
cache: storefront.CacheShort(), // cache di 60 secondi
});
// Nessuna cache per dati personalizzati (cart, customer)
const customerData = await storefront.query(CUSTOMER_QUERY, {
cache: storefront.NoStore(), // no-cache
});
液体から水素への移行テーマ
既存の Shopify テーマをお持ちの場合、Hydrogen への移行は重要なプロジェクトです。 推奨されるアプローチは段階的です。
- 優先ページを特定する:商品ページとコレクションページ 彼らはより多くのトラフィックを受け取ります。そこから始めてください。
-
Hydrogen をサブドメインとして使用する:
shop.tuodominio.com水素について、tuodominio.com液体のテーマについて。パフォーマンスをテストして測定します。 - チェックアウトを個別に移行する: Shopify 独自のメソッドでチェックアウトを処理します ネイティブ システム (チェックアウト拡張性) — 最初から書き直す必要はありません。
- 徐々に転送: ページごと、ルートごと。
知っておくべき水素の限界
-
チェックアウトはShopifyによって管理されます: チェックアウトは常にドメイン上で行われます
Shopify (
checkout.shopify.com)。 Checkout で外観をカスタマイズできます 拡張性がありますが、チェックアウトを独自のものに置き換えることはできません。 - 部分的なベンダーロックイン: 水素/酸素は Shopify でのみ機能します。 バックエンド。コマース プラットフォームを変更したい場合は、フロントエンドを書き直す必要があります。
- API レート制限: Storefront API にはレート制限があります。交通量が多い場合 高積極的なキャッシュ、またはサーバー側キャッシュを使用した BFF パターンを検討します。
結論と次のステップ
すでにエコシステムで働いている人にとって、水素 + 酸素は最も実用的な選択です Shopify をヘッドレス化したいと考えています。 Remix、GraphQL、エッジ コンピューティング、 ネイティブのチェックアウト管理は、高性能の店頭のための優れた基盤を提供します。
次の記事では、詳しく見ていきます Medusa.js、オープンソースの最良の代替品 ヘッドレス: 完全に自己ホスト可能なモジュラー アーキテクチャであり、ベンダー ロックインはありません。







