動的で、文脈を重視し、パーソナライズされていること。これが、コマースの未来です。Hydrogenは、クリエイティブなカスタムストアフロントを構築するためのReactベースのフレームワークであり、開発者が素早く構築をスタートして開発をするために必要なすべてを備えています。また、ShopifyのプラットフォームとAPIを活用して、動的でパーソナライズされた最高の購入エクスペリエンスを提供します。わたしたちは、以下の3つのコマースのニーズを満たすためにHydrogenを設計しました。
- 高速なユーザーエクスペリエンス:高速な読み込みとレスポンシブ
- マーチャントのための最高の機能:パーソナライズされた、文脈的で、動的なコマース
- 優れた開発者エクスペリエンス:簡単で、メンテナンスしやすく、楽しいこと
Hydrogenが提供する最適化されたReactコンポーネントにより、素早い立ち上げが可能です。
これらの目的は必然的に、一種の緊張状態をもたらします。それを認識することが重要です。静的な生成とエッジ配信によって速い読み込みを実現することができますが、重要コンテンツの遅延表示を引き起こすというクライアントサイドの課題をあきらめるか、パーソナライズする必要があります。反対に、サーバーからの動的なレスポンスをレンダリングすることは最初のレンダリングを遅くする可能性がありますが、正しくおこなえば、より良いコマースとショッピング体験が提供されます。ただし、Reactを活用したストアフロントのための効果的なストリーミングを行うサーバーサイドレンダリングと、賢いサーバーとクライアントのキャッシュを提供することは、ほとんどのチームにとって未解決の、開発体験の重要な課題となります。
Hydrogenは、パーソナライズされた文脈的で動的なコマースのために最適化されています。高パフォーマンスのストアフロントデータアクセスによる高速で効率的なサーバーサイドレンダリングは、そのような体験の必須条件といえます。わたしたちはユーザー体験を最適化するために、いくつかの戦略を活用しています。
- ReactのSuspenseによる高速な初回レンダリングのための、Streaming Server-side Rendering
- レンダリング後の効率的なコンポーネントレベルでのステート更新のための、React Server Components
- スマートキャッシュデフォルトを使用したビルトインサーバーとクライアントデータを取得するための基本仕様
- 動的なエッジ配信のための、フレキシブルなページとサブリクエストのキャッシュポリシー
いろいろありますので、1つずつ細かく見ていきましょう。
Streaming Server-side Rendering
購入者のパーソナライズドコンテンツが大量に含まれている商品ページを考えてみてください。ローカライズされた説明と価格、購入ヒストリーから得られるおすすめ商品のリスト、カスタムのCTAやプロモーションバーナー、さらにいくつかの多変量ABテストへのアサインなど。
クライアントサイドの戦略としては、空の商品ページスケルトンを素早くレンダリングして、一連のレンダリング後のブラウザによるfetchによって、要求されるコンテンツを取得してレンダリングすることになるでしょう。このようなクライアント側の往復は、ユーザーエクスペリエンスをすぐ損なうことになりがちです。
クライアントサイドのレンダリングとサーバーサイドレンダリング
Client-side rendering (CSR)の場合、通常は重要ページコンテンツの遅延表示という結果になります。つまり、LCPが遅くなります。代替戦略は、Server-side rendering (SSR)によってデータをサーバーで取得し、それをレスポンスで返すことです。これはRTTを排除して最初のコンテンツとlargest contentful paints(LCP)を近づけることに役立ちますが、遅いtime-to-first-byte (TTFB)という犠牲がともないます。データでサーバーがブロックされるためです。そこで、ストリーミングSSRが重要な最適化戦略となります。
Streaming Server-side Renderingは、高速でブロックされないレンダリングを可能にします。
Hydrogenは、Suspenseを使った新しいReact 18 alpha streaming SSR APIを採用しているため、重要なパフォーマンス上のメリットが得られます。
- 高速TTFB:ブラウザはHTMLページのシェルを、サーバーサイドのデータ取得をブロックすることなくストリーミングします。これは、すべてのクエリが解決するまでTTFBがブロックされる「標準の」SSRとは対照的です。
- Progressive hydration:サーバーサイドのデータ取得が解決すると、データはHTMLレスポンスにストリーミングされます。Reactのランタイムは漸進的に個々のコンポーネントのステートをhydrateします。余計なクライアントの往復やコンポーネントツリー全体のレンダリングのブロックはありません。ということは、ブラウザによってページがストリーミングされ構成されると、個別のコンポーネントがcustom loading statesを表示することが可能です。
ストリームと漸進的なhydrate、そしてアプリケーションをレンダリングする機能によって、高速TTFBが実現し、CSRのクライアントサイドでの連鎖を排除します。これは、動的で高パフォーマンスなコマースにとって、最適といえるでしょう。
React Server Components
Server Componentsによって開発者はサーバーとクライアントにまたがるアプリの構築ができます。クライアントサイドアプリのリッチな双方向性と従来のサーバーレンダリングの向上したパフォーマンスが組み合わさっているのです
Server Componentsは、パフォーマンスの高いストアフロントを提供するうえで欠かせないもう1つの基本要素です(わたしたちはそう信じてReactコアチームとコラボレーションを続けてきました)。RSCによって、クライアントとサーバーロジックおよびコンポーネント間の懸念を分離することができ、ホストのダウンストリームのメリットを得ることが可能になります。
- バンドルサイズに影響を与えず、バンドルサイズを縮小するサーバーだけのコード
- カスタムおよびプライベートなサーバーサイドのデータソースへのサーバーサイドアクセス
- サーバー+クライアントコンポーネントのシームレスな統合と明確に定義されたプロトコル
- ストリーミングレンダリングと漸進的なhydreation
- クライアントのステートを保存するsubtreeとコンポーネントレベルのアップデート
- 適切な場面でのサーバーとクライアント間のコード共有
Server Componentsは多くのReact開発者にとって新たな基本スキルとなり、多少のラーニングカーブがありますが、わたしたちは10ヶ月ほど携わってみて、そのアーキテクチャとパフォーマンスに大きなメリットがあることを確信しています。まだ体験されていない方は、RFCを読み、概略動画を視聴して、RSCに関するHydrogenドキュメントをチェックしてみてください。
効率的なデータ取得、コロケーション、キャッシング
高速なサーバーサイドレスポンスを提供するには、スピードがあり効率的なファーストパーティ(Shopify)とサードパーティのデータアクセスが必要です。Oxygen(Shopifyがホストする分散型のV8によるworkerランタイム)でデプロイすると、Hydrogen server componentsはローカルホストのスピードでStorefront APIのクエリを実行します。ストアデータはコロケーションされ、ミリ秒単位の位置にあります。サードパーティの取得の場合、ランタイムはスマートキャッシュデフォルトと構成可能なキャンシング戦略で強化された標準Fetch APIを当てます。
- スマートデフォルトキャッシングポリシー:keyの生成とキャッシュTTL
- キャッシュkey、TTL、キャッシングポリシーのカスタマイズとオーバーライド機能
- stale-while-revalidateを介した非同期データリフレッシュのビルトインサポート
Shopifyデータへのアクセスの詳細はuseShopQueryのドキュメント、効率的なデータ取得については取得ポリシーとオプションをご参照ください。
動的なサービスとエッジ配信の最高の組み合わせ
Hydrogenを採用しても、すべてのデータをサーバーから取得しないといけないわけではありません。逆に、重要ではないコンテンツをクライアントから延期またはlazyloadさせることは、良い実践例だといえます。優先度の低いコンテンツは通常のReactパターンとブラウザAPIを使って読み込めます。たとえば、IntersectionObserverを使ってコンテンツをいつスクリーンに表示させるかを決定し、必要に応じて読み込ませることができます。
同様に、すべてのリクエストがサーバーでレンダリングされる必要もありません。ページと静的なコンテンツまたは頻繁に更新されないコンテンツのサブリクエストは、エッジ配信が可能です。Hydrogenは開発者に柔軟性をもたらします。重要でパーソナライズされた文脈的なコンテンツをサーバーでレンダリングして提供でき、可能なかぎり最高のパフォーマンスを誇ります。またクライアントサイドのfetch機能とReactアプリケーションの双方向性というパワーもしっかり利用できるのです。
考慮すべき重要事項は、どのアーキテクチャを採用するか、ではありません。いつ、サーバーサイドレンダリングや、クライアントサイドの取得、エッジ配信を使用して最高のコマース体験を提供するかを決めることです。この決断は、ページやコンポーネントレベルで可能です。
たとえば、通常は静的なアバウトページやマーケティングページは、安全にキャッシュでき、CDNエッジから直接提供可能で、stale-while-revalidate戦略によって非同期でrevalidateされます。エッジ配信へのオプトインは、Hydrogenストアフロントのどのレスポンスでも、数回のキーストロークで実現します。この機能と、上述したfetch APIによる詳細で最適化されたサブリクエストを組み合わせ、キャッシングによってデータ更新とrevalidation戦略を完全に制御できます。
すべてを1つに
パフォーマンスが良く、動的で、文脈的で、パーソナライズされたコマース体験を提供することは、複数のレイヤーにおける最適化を要求します。今までは、このような領域はリソース豊富なごく限られたエンジニアチームに属するものでした。HydrogenとOxygenの目標は、このフィールドを平らにすることです。
- フレームワークがすべてのストリーミングを抽象化します
- コンポーネントはShopify API向けに調整されています
- Oxygenのランタイムは世界中にレンダリングを分散して配信します
わたしたちが望むのは、差別化されないテクノロジーの繋ぎ合わせの代わりに、HydrogenとOxygenを採用することで開発者が素晴らしいコマース体験の構築と生産工程に専念でき、モダンでレジリエントなストアフロントを強化していくことです。
Hydrogenを試して、ドキュメントを読み、フィードバックをお願いします。Let’s build!
原文:Ilya Grigorik 翻訳:深津望