Amazon Web Services ブログ

Amazon CloudFront、Amazon S3、AWS Lambda を使用して圧縮された WebGL ウェブサイトを配信する

本ブログは “Serving compressed WebGL websites using Amazon CloudFront, Amazon S3 and AWS Lambda” を翻訳したものです。

この投稿では、圧縮された WebGL の Web サイトをエンドユーザーに配信する方法について説明します。要求されたウェブページ内のファイルが圧縮されると、転送サイズが小さくなり、ダウンロードが速くなり、クラウドストレージ料金が下がり、データ転送料金が下がります。読み込み時間の改善は、視聴者のエクスペリエンスとリテンションに直接影響し、ウェブサイトのコンバージョンと発見しやすさを向上させるのに役立ちます。

WebGL を使用すると、ブラウザーの URL を介してアクセスしながらも、ウェブサイトをより没入感のあるものにすることができます。ユースケースの例には、バーチャルリアリティ(VR)アプリケーション(オンライン教育、3D 製品ビジュアライゼーション、カスタマイズされた電子商取引など)、バーチャルツイン(機器や施設のオンラインレプリカの作成)などがあります。

本稿で紹介するソリューションでは、Amazon CloudFront を使用して、圧縮された静的コンテンツ (HTML/CSS/JS) をエッジで配信する WebGL ウェブサイトを構築する方法を学習します。また、CloudFront のオリジンで 3D モデルを圧縮する方法 (このブログ記事の例では、Amazon Simple Storage Service (Amazon S3) を使用してウェブサイトのコンテンツをホストしています)、および AWS Lambda を使用して S3 にアップロードされたオブジェクトを自動的に圧縮する方法についても説明します。

圧縮と WebGL について

HTTP 圧縮は、Web サーバーと Web クライアントに組み込むことで、転送速度と帯域幅の使用率を向上させることができる機能です。この機能は、転送、キャッシュ、またはその他の方法で参照されるリソースが圧縮されていることを示す HTTP ヘッダーを使用して、サーバーとクライアント間でやりとりされます。サーバー側である Amazon CloudFront は、Content-Encodingヘッダーをサポートしています。

今日のほとんどのブラウザーはHTTPヘッダ(Accept-Encoding: deflate、br、gzip)によるbrotliおよびgzip圧縮をサポートしており、クライアント側ではサーバのレスポンスヘッダーを扱うことができます。つまり、ブラウザーはWeb ページをビューアにレンダリングする前に、Web サーバーからコンテンツをダウンロードしクライアント側で自動的に解凍します。

WebGL は特定の 3D アセットフォーマットをサポートしています。例は次のとおりです。

  • glTF: 3Dシーンとモデルの標準ファイルフォーマット。glTF ファイルは、gltf または glb の 2 つのファイル拡張子のいずれかを使用します。gltf ファイルは自己完結型であることも、外部バイナリおよびテクスチャリソースを参照する場合もありますが、.glb ファイルは完全に自己完結型です。
  • Babylon.js ファイル:Babylon.js は、シーンを記述するために JSON ファイル形式を使用します。
  • Wavefront .obj: OBJ は、Advanced Visualizerのアニメーションパッケージのために Wavefront Technologies によって最初に開発されたジオメトリ定義ファイル形式です。ファイル形式はオープンで、他の 3D グラフィックスアプリケーションベンダーによって採用されています。

ソリューションの概要

このサンプルアプリケーションでは、クラウドオブジェクトストレージサービスであるAmazon S3、受信リクエストまたはイベントに基づいてコードを実行するサーバーレスコンピューティングサービスであるAWS Lambda、Amazon S3 などの任意の AWS オリジンとシームレスに動作する高速なコンテンツ配信ネットワーク(CDN)であるAmazon CloudFrontを使用しています。次の図がソリューションのアーキテクチャです。本ソリューションのAWS サーバーレスアプリケーションモデル (SAM)を用いたデモおよびウォークスルーについて後述します。

図 1: CloudFront と Lambda を使用したウェブサイトと 3D アセットの圧縮

手順の概略:

  1. ウェブサイトのホスティングに使用される S3 バケットにオブジェクトをアップロードします。
  2. オブジェクトがソース S3 バケットにアップロードされると、S3 は Lambda 関数をトリガーします。
  3. Lambda は 3D モデルファイルを圧縮し、バケットの別フォルダに再アップロードします。
  4. Cloudfront は S3 バケットをオリジンとしてウェブサイトサービスを提供します。
  5. クライアントのブラウザーに圧縮された Web サイト(HTML、CSS、JS、および 3D アセット)が配信されます。ブラウザーは、クライアント側でコンテンツを自動的に解凍します。

AWS サーバーレスアプリケーションモデル (SAM) を使用したデモ

ソースコードの表示

前提条件

サンプルアプリケーションをデプロイするには、次のものが必要です。

  • リソースを作成するために必要なアクセス権限を提供する AWS 認証情報。この例では、管理者権限の認証情報を使用します。
  • AWS SAM CLI がインストールされていること。
  • GitHub リポジトリがクローンされていること。

デプロイの手順

  • 複製された リポジトリのディレクトリに移動します。または、sam init コマンドを使用して、リポジトリのURL を貼り付けます。
    AWS SAM の起動プロンプト
  • AWS SAM アプリケーションをビルドします。
    sam build
  • AWS SAM アプリケーションをデプロイします。
    sam deploy --guided
    注:SAM ガイド付きデプロイでは、グローバルに一意な S3 バケット名を作成するように求められます。必ず小文字と数字のみを使用してください。
  • デプロイが成功したら、「SAM デプロイの出力」セクションの CloudFront URL を書き留めます。
    注:デプロイには約 15 分かかります。

ソリューションのテスト

  1. AWS マネジメントコンソールで、新しく作成した S3 バケットに移動します。
  2. クローンしたリポジトリから、website/ の下にあるすべてのファイルを S3 バケットのルートフォルダにアップロードします。
  3. ブラウザを開き、開発者ツールを有効にして CloudFront URL にアクセスします。

図 2: glb モデルの圧縮率が 46% であることを示している、シンプルな Babylon.js ページ。Amazon Sumerian Hosts の「Grace」は CC BY-SA 4.0 の下でライセンスされています。

うまくいっていれば、ほとんどのウェブサイトコンテンツ(3D アセットと静的コンテンツ)が圧縮形式(brotli と gzip)でクライアントに提供されていることがわかります。

ウォークスルー

このスタックは、次のリソースを作成および設定します。

CloudFront ディストリビューション

次の設定の CloudFront ディストリビューションが作成されます:

このソリューションでは、CloudFront は次の利点を提供します。

  1. CloudFront のデフォルト証明書を使用して HTTPS 経由でウェブサイトを配信します。HTTPS はウェブサイトを保護することに加え、音声サポート(オンラインミーティング、VRホストで会話を行う、など)を有効にする場合はブラウザーで必要となります。
  2. 静的な Web サイトファイル (.html、.js、.css など) のエッジでの自動オブジェクト圧縮を有効にします。10 MB 未満のファイルが圧縮されます。

S3 バケット

S3 バケット名はデプロイ時に自由に設定できます。次の設定が行われます:

  • プライベートアクセス
  • バケットポリシーでアクセスをCloudFront OAI のみに制限する

Lambda 関数

この関数はPython のランタイムを使用し、次のコードロジックを持ちます。

  • Lambdaでは ‘/tmp/’ を一時的な読み取り/書き込み作業用ディレクトリとして使用します。この領域のサイズは 512 MB で固定です。
  • デフォルトの圧縮レベルで gzip を使用して 3D アセットファイルを圧縮します。
    注:さまざまな圧縮レベルを試すことができますが、圧縮レベルを上げると、(gzipの性質上)ファイルサイズの削減観点での効果は低下し、ブラウザーの解凍時間は長くなる可能性があります。ブラウザーの解凍時間はオーバーヘッドとなりますが、圧縮することのメリットはそのデメリットを上回ります。
    「ブラウザーの処理終了時間 = アセットのダウンロード時間 +クライアント側ブラウザーでのアセット解凍時間」
  • メタデータ (Content-Encoding:gzip) をファイルに追加します。
  • アセットの元のファイル名・拡張子を維持します (つまり、ファイル拡張子に.gz サフィックスを追加しません)。これは、3D エンジンの JavaScript コードを透過的に保つために重要です。

    図 3: 元のファイル拡張子を使用した Babylon.js Append 関数の使用例

  • 圧縮ファイルを S3 にアップロードし直し、圧縮されていない元のファイルを削除します。

Lambda には S3 トリガーが設定されており、オブジェクトのアップロード時に関数が自動的に呼び出されます。トリガーは、スコープ内のすべての 3D アセットタイプに対して追加されます。この例では、サフィックスは 3 つのファイルタイプ (gltf、glb および babylon) に指定されます。この設定は、プロジェクト内のすべてのファイルに対して Lambda 関数がトリガーされないようにするために重要です。

図 4: Lambda 関数の S3 トリガーの設定

関数のメモリは 512 MB に設定され、タイムアウトは 60 秒に設定されています。この構成では、13 MB のアセットの圧縮に平均 2 秒かかります。必要に応じて、これらのパラメータを変更します。Lambda をトリガーするために必要なアクセス許可が S3 バケットに追加されます。またLambda に対しても、S3 バケットに対しオブジェクトの取得および保存するためのアクセス許可が追加されます。

プロジェクトの例

VR Child Monitor実際の 3D シーンをナビゲートすることもできます)のような大規模なプロジェクトでは、分析すると、ウェブサイトの読み込みの「完了」時間の改善が 57.4% 改善されたことが示されます。ウェブサイトは完全に読み込まれるのに非圧縮のアセットの場合は56 秒かかるのに対し、圧縮されたアセットの場合は27 秒となります。AWS からビューワーへのデータ転送 (MB 単位) は 54.3% 削減されます。

図 5: エンドユーザーに配信される非圧縮アセット

図 6: エンドユーザーに配信される圧縮アセット

注:画像ファイル(.png、.jpg など)は、もともと圧縮されているフォーマットのため、圧縮のメリットはありません。gzip 圧縮を追加して得られるのは、3 ~ 4% 程度の小さな改善にとどまります。

クリーンアップ

今後の課金が発生しないようにするには、次のようにリソースを削除します。

  • S3 バケット内のすべてのオブジェクトを削除します。
  • CloudFormation スタックを削除します。

まとめ

この投稿では、AWS クラウドで WebGL ベースのウェブサイト用の圧縮パイプラインをデプロイする方法を紹介しました。Amazon S3AWS LambdaAmazon CloudFront を使用しているため、疎結合かつサーバーレスです。

デモでは、エンドユーザーにウェブサイトをより速く提供することにおけるコンテンツ圧縮の利点を紹介しました。これは、特にサイズの大きなシーンではより重要になります。また、ストレージとデータ転送のコストも節約できます。JavaScript コードの変更は不要で、パイプラインは完全に自動化されています。

Raspberry Pi、S3、Amazon LexAmazon PollyAWS IoT coreを使用した私の 3D プロジェクトもご確認ください:キッズモニターのデモ大気汚染デモがあります。

著者について

Ahmed Elhaw

Ahmed Elhaw はアマゾンウェブサービス (AWS) のシニアソリューションアーキテクトで、テレコム、ウェブ開発とデザイン、空間コンピューティング、AWS サーバーレステクノロジーなどのバックグラウンドを持っています。彼はお客様に技術的なガイダンスを提供し、AWS を最大限に活用するソリューションの構築とアーキテクティングを支援することを楽しんでいます。仕事以外では、コーディングを楽しんだり、子供たちと過ごしたり、ビデオゲームを楽しんだりしています。

翻訳はソリューションアーキテクトの西坂が担当しました。原文はこちらです。