iframe依存からの脱却 ── Litで実現するWeb ComponentsによるUI共有基盤

iframe依存からの脱却 ── Litで実現するWeb ComponentsによるUI共有基盤

はじめに

こんにちは、ZOZOTOWN企画開発部 企画フロントエンド2ブロックのパクサンイです。普段はZOZOTOWNにあるCMSベースのLPページのメンテナンスや機能追加、企画LPページ環境のメンテナンスを担当しています。

ZOZOTOWNの複数のWebアプリケーション間で、プロモーション用ランディングページコンポーネントを共有するために、LitベースのWeb Componentsを導入しました。本記事ではその事例を紹介します。

ZOZOTOWNでは多数のLPページが開設・更新されており、従来はiframeを使った埋め込み方式でUIを共有していました。しかし、この方式にはさまざまな課題が存在し、レガシー環境からNext.jsベースの新環境へのリプレイスを進める中で、フレームワークに依存しないUI共有アーキテクチャが必要となりました。

本記事では、iframeベースの共有方式が抱える具体的な課題と、LitベースのWeb Componentsを採用した理由と選定プロセスを解説します。さらに、フレームワーク非依存なコンポーネント共有基盤を設計・実装する中で得た経験を共有します。

対象読者

  • マルチWebアプリケーション環境でUI共有に課題を感じているフロントエンドエンジニア
  • iframeを使ったUI共有方式の代替手段を探している方
  • Web Componentsの導入を検討している方

目次

背景・課題

ZOZOTOWNフロントエンドのマルチWebアプリケーション構成

現在、ZOZOTOWNのフロントエンドは3つのマルチWebアプリケーションで運用されています。

リポジトリ 説明 主な役割
リポジトリA(レガシー環境) 統合リポジトリ 既存の全ページを管理
リポジトリB(リプレイス環境) コアメインページ ホーム、カート、検索結果、商品詳細ページなど
リポジトリC(リプレイス環境) 企画ページ フルスクラッチLP、CMS活用LP

レガシー環境では複数のサービスが単一リポジトリで管理されていたため、共通UI共有に関する課題はありませんでした。しかし、リプレイス後にマルチWebアプリケーションが増えたことで、従来の方式ではUIを再利用できなくなりました。

LPコンポーネントの共有仕様

ZOZOTOWNでは特定のLPコンポーネントを複数のページで表示しています。一部のページでは以下の2つの形態で表示されます。

  1. 単独ランディングページ — header/footerを含むフルページ
  2. モーダル表示 — 特定ページのバナークリック時に、header/footerなしでコンテンツセクションのみをモーダルで表示

つまり、ほぼ同一のUIでありながら、header/footerの有無、SEOメタタグ、計測用トラッキングスクリプトの有無などで差異がある仕様でした。

ZOZOTOWNにおけるLPコンポーネントの共有仕様を示す図。単独ランディングページとモーダル表示の2つの表示形態を表している

従来のiframeベース共有方式とその課題

リプレイス後は以下の方式でUIを共有していました。

環境 運用方式
リポジトリA(レガシー) LPページ配信 + iframe用LPページ(header/footerなし)配信
リポジトリB・C(リプレイス) 特定ページにバナー表示 → クリック時にモーダル内でiframeとしてリポジトリAのLPを埋め込み

このiframe方式には以下の課題が存在していました。

1. レイアウト制御の煩雑さ

iframeは独立したドキュメントを読み込むため、フレームサイズの調整や使用箇所ごとの非表示領域の処理は対応していたものの、煩雑な部分がありました。

2. UI制御の複雑化

各バリエーションに応じて非表示にすべき子コンポーネントもあり、クエリパラメータやpostMessageで解決できるものの、ケースが増えるほど複雑化しました。

3. SEOの制約

検索エンジンはiframe内のコンテンツをsrc側の所有として認識するため、SEO上の制約がありました。

アプローチ:Web Componentsの導入

要件整理

上記の課題を解決するために、以下の4つの要件を整理しました。

要件 説明
各アプリのデプロイなしにUI更新 iframe方式の利点であった各マルチWebアプリケーションのデプロイなしにUI変更が反映されることを維持
iframe脱却 各アプリケーションでネイティブにUIをレンダリング
フレームワーク非依存 React、Vueなど、どのフレームワークでも使用可能であること
軽量バンドルサイズ 利用側に負担のない最小限のサイズを維持

技術選定:Lit基盤Web Components

Web ComponentsとLitライブラリのロゴ

Web Componentsはブラウザのネイティブコンポーネントモデルであり、特定のフレームワーク(React、Vueなど)に依存せず、ブラウザが直接理解する標準技術です。主に以下の3つの中核技術で構成されています。

  • Custom Elements:開発者が独自のHTMLタグを定義できる。タグ名にはハイフン(-)を含む規約がある。
  • Shadow DOM:コンポーネントのスタイルとマークアップを外部ページから隔離(Encapsulation)する。
  • HTML Templates<template><slot>要素により、再利用可能なマークアップ構造を定義する。

このWeb Componentsをより効率的に開発するため、Litライブラリを採用しました。

Litを選択した理由

選定基準 Litの特徴
バンドルサイズ 約5KB(minified + compressed)で非常に軽量
リアクティブプロパティ Reactive Propertiesにより状態変更時に自動再レンダリング
テンプレート Tagged Template Literalsベースで別途コンパイル不要
パフォーマンス Virtual DOM diffingなしに動的部分のみを直接更新
相互運用性 すべてのLitコンポーネントはネイティブWeb Componentであり、HTMLを使うあらゆる場所で動作

npmパッケージ方式を除外した理由

LPページはテキスト更新の頻度が高く、UIも不定期に変更されます。npmパッケージで運用すると、変更のたびに各環境でパッケージ更新+デプロイが必要となり、運用負荷が大きいため除外しました。

設計・実装

全体アーキテクチャ

コンテンツ共有専用リポジトリを新たに構築し、以下の設計原則を適用しました。

1. 利用側アプリケーションによるデータ取得・加工

ZOZOTOWNにはページアクセス時に初期設定すべき値やAPIフェッチのためのロジックが各アプリケーションに存在します。これらのロジックをコンテンツ共有専用リポジトリにも含めると管理が二重になりメンテナンス負荷も大きくなるため、このリポジトリではUIレンダリングのみを責任範囲としました。

利用側の親アプリケーションでデータを取得・加工してpropsで渡す形式を採用しています。

利用側アプリケーションがデータを取得・加工し、Web Componentにpropsで渡すアーキテクチャのデータフロー図

2. Lit ContextによるProps Drilling防止

UI内部で必須的に共有すべき情報(デバイス種別、性別など)は、Lit Contextを活用したカスタム要素を設けて処理しました。

Lit ContextはReactのContext APIと同様の概念で、Props Drillingなしに上位から下位コンポーネントへデータを渡すことができます。

Lit Contextを使用してProps Drillingなしにデータを共有するコード例

3. Scriptローディングによる独立したUI更新

各Webアプリケーションで別途デプロイなしにUI変更が可能なよう、Scriptローディングを採用しました。各アプリケーションでは<script>タグで必要なコンポーネントのJSファイルを読み込み、クライアントでWeb Componentがレンダリングされます。

4. Shadow DOMからLight DOMへの切り替え

Web Componentsの代表的な特徴であるShadow DOMは、スタイルを完全に隔離し、コンポーネント内部のCSSが外部に影響せず、外部CSSも内部に影響しません。

しかし、今回のケースでは、Shadow DOMで隔離して管理するUIではなく、利用側から自由にスタイルだけでなく要素にもアクセスできることが重要でした。そのため、Shadow DOMの代わりにLight DOMを採用しました。

ビルド・配信

Viteを使用してLit基盤Web Componentをビルドし、S3にデプロイしてCDN経由で配信します。

全体フロー

LPコンポーネント開発側(コンテンツ共有専用リポジトリ)

  1. Lit + Vite dev serverでローカル開発
  2. 各テスト環境にてHTML + JSで動作確認
  3. 問題なければ各環境(S3)にデプロイして確認

利用側Webアプリケーション

  1. SSR時にCMS APIでデータ取得(スケジュールに応じて変更されるテキストなどはCMSで管理)
  2. クライアントで<script>タグによるJSファイルローディング、Web Componentのレンダリング
  3. カスタムタグへCMS API仕様に合わせたデータをpropsで渡す

LPコンポーネント開発から利用側Webアプリケーションでの表示までの全体フロー図

効果

この仕組みの導入により、以下の効果が得られました。

  • マルチWebアプリケーション間でiframeを使わずにUIコンポーネントを共有できるようになった
  • 各アプリケーション側のリリース(デプロイ)なしでコンテンツ更新が可能になった
  • 利用側からスタイルだけでなく要素へのアクセスも自由に可能になった(Light DOM採用)
  • CMS連携により、エンジニア以外でも直接スケジュールベースのデータ管理が可能に

学んだこと

Litを通じて開発する中で、Web Componentsのベースとなるウェブ標準技術をより深く理解し、関心を持つようになりました。また、CSS変数などを活用してJavaScriptなしにCSSだけでスタイルを制御する方法も知ることができました。

今後の課題

Web Components公式のSSR対応はまだ限定的ですが、Lit SSRなど複数の解決策がライブラリやコミュニティで共有されています。現在、このプロジェクトで管理しているLPページの仕様ではWeb ComponentのSSRは不要ですが、将来に備えた準備は必要だと考えています。

また、現在の運用方式では、Scriptローディング+CMSデータ連携という構造上、テストが非常に重要であり補強が必要です。

今後の展望

移行すべきLPページが多数残っており、段階的にマイグレーションを進めていく予定です。より小さな単位の共用コンポーネントもこの基盤で管理できるよう拡張を検討しています。また、可能であれば、ネイティブアプリケーションでの活用も検討したいと考えています。

まとめ

本記事では、ZOZOTOWNのマルチWebアプリケーション環境におけるiframeベースUI共有方式の課題を解説しました。また、LitベースのWeb Componentsを活用したフレームワーク非依存のコンテンツ共有基盤の構築事例を紹介しました。

ReactベースであればReactでもUIを共有する方法はあります。しかし、今後どのフレームワークでも問題なく移植できるWeb Componentsを選択し、メインスタックと共存しながら運用するのもよいのではないでしょうか。同様の課題をお持ちの方の参考になれば幸いです。

最後に

ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。

corp.zozo.com

参考資料

カテゴリー