【必読】なぜ今、Aura ではなく LWR を選ぶべきなのか?

【Spring ’26】Experience Deliveryのデータ鮮度とキャッシング戦略:Publish-Time Freezingからの脱却とTTL管理

この記事はバージョン Spring ’26 において執筆しています。
現在の動作と異なる場合がありますので、ご認識おきください。

Salesforceのデジタル体験(Digital Experience)開発において、長年私たちアーキテクトが前提としてきた「常識」が、Experience Deliveryの登場によって大きく覆されようとしています。

これまでのLWRサイト運用において、パフォーマンスと安定性を担保する要であった「Publish-Time Freezing(公開時の凍結)」モデル。Experience Deliveryへの移行は、この静的な世界から、動的なSSR(Server-Side Rendering)と高度なキャッシング制御が支配する世界へのパラダイムシフトを意味します。

今回は、この移行に伴う「データ鮮度」と「キャッシング戦略」の劇的な変化について、アーキテクチャの観点から深掘りしていきます。

レガシーパラダイム:「Publish-Time Freezing」の功罪

Experience Deliveryの革新性を理解するには、まず従来のLWRサイトがどのように動いていたかを振り返る必要があります。

標準的なLWRモデルでは、「公開(Publish)」ボタンを押した瞬間がすべてでした。このプロセスにおいて、プラットフォームはJavaScriptリソース、ビュー、コンポーネント定義を生成し、その状態を「凍結(Freeze)」します。

  • 不変性(Immutability): 公開時のコードバージョンが固定されるため、バックエンドでLWCのコードを更新しても、再公開するまではサイトに反映されません。これは「誤ってライブサイトを壊さない」という意味で強力な安定性を提供しました。
  • 長期キャッシュ: 凍結されたアセットは静的ファイルとしてCDNにキャッシュされ(通常約150日間)、2回目以降のアクセスを高速化していました。

しかし、このモデルには「初期ロードの重さ(CSRの負担)」と「データ鮮度の乖離」という課題がありました。ユーザーにはまず「空のHTMLシェル」が届き、ブラウザがJavaScriptを解釈し、その後に初めて最新データを取得しにいく――いわゆる「ウォーターフォール」型の読み込みです。これにより、First Contentful Paint (FCP) やSEOに限界が生じていました。

SSRによる変革:リクエスト時のスナップショット

Experience Deliveryは、この「凍結」のタイミングを「公開時」から「リクエスト時」へと移動させます。

Node.jsベースのランタイムがリクエストをインターセプトし、サーバー上でコンポーネントロジックを実行。データを取得して完全にポピュレートされたHTMLを生成します。CDNはこの「サーバーがレンダリングした結果(HTML)」をキャッシュします。

つまり、コードは公開時にバージョン管理されますが、レンダリングされる出力(データを含むHTML)は、キャッシュポリシー(TTL)に従って更新されることになります。これにより、ユーザーは常に(TTLの範囲内で)最新のデータが含まれた高速なページを受け取ることができます。

getServerData フックとTTLによる鮮度管理

この新しいモデルにおいて、データ鮮度の主導権を握るのが getServerData フックです。従来のWire Adapterに代わり、サーバーサイドでのデータ取得を担当します。

最も重要なのは、開発者が cache オブジェクトを通じて Time-To-Live (TTL) を秒単位で制御できる点です。

実装例:TTLを設定したデータ取得

以下に示すコードは、Experience Deliveryの技術仕様(フックの役割や戻り値の構造)に基づき、具体的なユースケース(商品詳細ページ)を想定して作成した実装イメージです。

DXforce Point for Developers

実装上の注意
以下のコードはそのままコピー&ペーストしても動作しません。ご自身の環境で検証が必要です。

  • fetchProductData: 実際のデータ取得ロジック(Apex呼び出しやAPIコール)に置き換える必要があります。
  • recordId: URLパラメータ名は、サイトのルーティング設定(route 定義)に依存します。
// 【推測】インポートパスは環境により異なる可能性があります
// ※ レポートおよび公式仕様には型名のみ記載があり、具体的なimport元パッケージの記載はありません
import { SsrRequestContext, SsrDataResponse } from 'experience/ssr'; 

/**
 * サーバーサイドでのデータ取得フック
 * @param context SSRリクエストコンテキスト
 * @returns SSRデータレスポンス(プロパティ、キャッシュ設定、マークアップ)
 */
export async function getServerData(context: SsrRequestContext): Promise<SsrDataResponse> {
    
    // 【事実】context.params からURLパラメータにアクセスできることは仕様(Fact)です
    // 【環境依存】'recordId' というパラメータ名は、各サイトのルーティング設定に依存します
    const id = context.params.recordId; 

    // 【実装依存】ここは完全にプレースホルダーです。実際のロジックに置き換えが必要です
    // 例: Apexメソッドの呼び出し、GraphQL、外部APIへのfetchなど
    const productData = await fetchProductData(id);

    return {
        // 【事実】ここで返した props がLWCの @api プロパティに入ります
        props: {
            product: productData
        },
        
        // 【事実】cache: { ttl: '...' } という構文でCDNキャッシュ期間を制御するのは仕様(Fact)です
        cache: {
            // このページのキャッシュ有効期限を60秒に設定
            ttl: '60s'
        },
        
        // 【事実】markup プロパティで <head> 内のタグを操作できるのも仕様(Fact)です
        markup: {
            links: [
                { rel: 'canonical', href: `https://example.com/products/${id}` }
            ]
        }
    };
}

最短TTLの法則(Shortest TTL Rule)

ここで注意すべきは、単一ページ内に複数のSSRコンポーネントが存在する場合の挙動です。LWRエンジンは「最短のTTL」を採用します。

あるコンポーネントが「60秒」、別のコンポーネントが「300秒」を要求した場合、ページ全体のキャッシュはより鮮度が求められる「60秒」に設定されます。キャッシュ期間を長くしすぎればデータが陳腐化し、短くしすぎればSSRの負荷が高まりCDNの恩恵が薄れます。このバランス調整が、これからのアーキテクトの腕の見せ所となります。

【重要】認証済みアセットと「パブリックキャッシュ」の罠

Experience Deliveryへの移行において、セキュリティ観点で最も警戒すべき落とし穴があります。それは「認証済みページの静的アセットもパブリックにキャッシュされる」という仕様です。

Publish-Time Freezingモデルでは、アクセス権限によってリソースが保護されていました。しかしExperience Delivery(特に現在のBeta仕様)では、パフォーマンスを最大化するために、サーバーレンダリングされたHTMLやアセットがパブリックなCDN層にキャッシュされる可能性があります。

これはつまり、「ユーザー固有の機密情報(個人名や口座番号など)を、SSRで生成されるHTMLに直接埋め込んではならない」ということを意味します。もし埋め込んでしまえば、そのHTMLがキャッシュされ、認証していないゲストユーザーや他のユーザーに配信されてしまうリスクがあります。

アイランズ・アーキテクチャによる解決策

この「高速なキャッシュ」と「ユーザー固有データ」の矛盾を解決するのが、以前の記事でも触れたアイランズ・アーキテクチャ(Islands Architecture)です。

Islands Architecture のイメージ(Gemini Nano Banana が生成)

私たちはコンポーネントを明確に分類し、適材適所でレンダリング戦略を選択する必要があります。

分類レンダリング用途・戦略
SSR Only / With Hydrationサーバーパブリックデータ、共通コンテンツ用。
getServerData で取得し、CDNにキャッシュさせる。SEOに強く、高速表示が可能。
CSR Onlyクライアントユーザー固有データ、機密情報用。
サーバーからは空のプレースホルダーとして送信し、ブラウザ上で認証済みユーザーとしてデータを取得(Wire Adapter等)する。

例えば、ヘッダーの「ようこそ、〇〇さん」という表示や、マイページのアカウント情報は、必ずCSR(Client-Side Rendering)のアイランドとして実装し、サーバーサイドのキャッシュに含まれないように設計しなければなりません。

まとめ:ハイブリッド・アーキテクトへの進化

Experience Deliveryは、単にLWRサイトが速くなるというだけの話ではありません。「どのデータをキャッシュし、どのデータをリアルタイムにするか」「どこでレンダリングするか(サーバーかクライアントか)」という意思決定のプロセスそのものを変革します。

Spring ’26以降の本格導入に向け、私たちにはコンポーネントの移植性(Portability)を監査し、TTLを適切に設計し、セキュリティを考慮したアイランド構成を組むスキルが求められています。

Data Cloudとの連携も視野に入れつつ、この新しいアーキテクチャを使いこなしていきましょう。

参考URL

Salesforce Spring ’26 Release Notes

Improve LWR Site Performance with Experience Delivery

Server-side rendering (SSR) in LWR

DXforceの管理人

福島 瑛二

2013年にJavaエンジニアとしてのキャリアをスタート。2019年にSalesforceと出会い、Salesforceエンジニアの道へ。

デザインや UI/UX の観点からもシステムを捉え、ユーザーにとって心地よい体験を実装することにやりがいを感じています。

CRM(顧客データ)や Data Cloud と連携した高度なサイトを目に見える形で表現できる Experience Cloud に大きな可能性を見出しており、バックエンドのデータ構造とフロントエンドの表現力を極めることがこれからの Salesforce エンジニアに求められるスキルだと確信しています。

Trailblazer: efukushima

福島 瑛二をフォローする

読者の声

タイトルとURLをコピーしました