Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Building a bilingual browser game with Astro and Cloudflare (and making the HTML actually cache)

2026年09月29日に「Dev.to」が公開したITニュース「Building a bilingual browser game with Astro and Cloudflare (and making the HTML actually cache)」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AstroとCloudflareを使いブラウザゲームを開発した記事。Astroでゲーム以外の静的ページを効率化し多言語対応。アカウント不要のセーブ方式を採用した。CloudflareのCDN-Cache-ControlでHTMLキャッシュを最適化し、表示速度を向上させた工夫を解説する。

ITニュース解説

ベトナムの揚げ魚ボール屋台をテーマにした料理ゲーム「Cá Viên Chiên」は、ブラウザで動作し、スマートフォンでの利用に最適化され、ベトナム語と英語に対応している。このゲームの開発過程で、開発者が特に注目した点や課題と解決策について解説する。

まず、このゲーム開発にAstroという技術を選んだ理由から説明する。ゲームのウェブサイトは、実際にゲームが動作する部分だけでなく、ゲームの紹介ページ、遊び方ガイド、ヒント、メニュー、FAQなど、多くの情報ページで構成されている。これらの情報ページは、検索エンジンからの訪問者にとって非常に重要であり、できるだけ表示が速く、安定していることが求められる。そのため、あらかじめ作成された静的なHTMLファイルとして提供されるのが理想的だ。Astroは、このような静的なHTMLファイルを効率的に生成する「静的サイトジェネレータ」と呼ばれる技術の一つで、ウェブサイトの多くの部分を静的ページとして構築するのに適している。一方、ゲーム本体は、Astroが生成したHTMLの中に「アイランド」と呼ばれる独立したコンポーネントとして組み込まれている。これは、特定の場所だけをJavaScriptで動的に動かすという考え方で、ゲーム本体のコードはフレームワークに依存しないシンプルなJavaScriptコード(約26KB)とCSS(約5KB)だけで構成され、非常に軽量に保たれている。

次に、多言語対応の仕組みについて説明する。このゲームはベトナム語と英語に対応しており、それぞれの言語ごとに/vi/や/en/といったURLのプレフィックスを設けている。例えば、ベトナム語版のページは/vi/about、英語版は/en/aboutのような形式になる。また、検索エンジンに対して各言語の代替ページを正確に伝えるために、hreflangというHTMLの属性を設定している。これにより、検索エンジンはユーザーの言語設定に応じて最適な言語のページを表示できるようになる。ウェブサイトのトップページであるルートURLの/にアクセスした場合は、ユーザーのブラウザが送信するAccept-LanguageというHTTPヘッダに基づいて、最適な言語のページへ自動的にリダイレクトされる仕組みだ。しかし、この自動リダイレクト機能は、キャッシュ(一時保存)の仕組みと相性が悪く、後述するHTMLのキャッシュがうまくいかない原因の一つとなった。

ゲームのセーブ機能については、ユーザーがアカウントを作成したり、サーバーにデータを保存したりする必要がないように工夫されている。ゲームの進行状況は、ユーザーのブラウザに内蔵されているlocalStorageという機能に自動的に保存される。購入時や一日の終わりなど、節目ごとにデータが保存される仕組みだ。もし別のデバイスでゲームを続けたい場合は、ゲーム内で生成される「セーブコード」をコピーし、新しいデバイスのゲームに貼り付けることで、簡単にデータを移行できる。これは、ゲームの状態を文字列データに変換(シリアライズ)する仕組みを利用しており、サーバーサイドのインフラを不要にすることで、開発と運用をシンプルに保っている。

今回の開発で最も興味深く、かつ困難だったのが、HTMLファイルのキャッシュに関する課題だ。ウェブサイトを高速化するためには、コンテンツをユーザーに近い場所で一時的に保存する「キャッシュ」が非常に重要となる。このゲームでは、CloudflareというCDN(コンテンツデリバリーネットワーク)を利用している。CDNは、世界中に分散配置されたサーバー(エッジサーバーと呼ぶ)にコンテンツを一時的に保存し、ユーザーに最も近いエッジサーバーからコンテンツを配信することで、ウェブサイトの表示速度を劇的に向上させる技術だ。 ウェブサイト内で使われる画像やJavaScript、CSSなどの「静的アセット」(ファイル名にハッシュ値が付加される_astro/*配下のファイルなど)は、キャッシュが非常に効果的に機能していた。これらはmax-age=31536000, immutableというHTTPヘッダが設定されており、約1年間は変更されないものとしてエッジサーバーやブラウザにキャッシュされるため、初めから問題なく高速に配信できていた。 しかし、HTMLファイルに関しては状況が異なった。リクエストごとにCloudflareのキャッシュステータスがcf-cache-status: DYNAMICとなり、常にオリジンサーバー(コンテンツの元のサーバー)にリクエストが届いていたのだ。その結果、TTFB(Time To First Byte、リクエストから最初のデータが届くまでの時間)が約250ミリ秒もかかっており、ウェブサイトの表示速度を遅らせる要因となっていた。

この問題を解決するため、Cloudflareのキャッシュルールを設定し、/vi/*や/en/*といったHTMLファイルもキャッシュの対象とした。しかし、それでもTTFBはほとんど改善されなかった。これは、オリジンサーバーがHTMLファイルに対してcache-control: public, max-age=0, must-revalidateというHTTPヘッダを返していたためだ。このmax-age=0という設定は「キャッシュはすぐに期限切れになる」という意味を持ち、must-revalidateは「必ず再検証が必要」という意味を持つ。Cloudflareのエッジサーバーは、このオリジンサーバーからの指示に従うように設定されていたため、たとえキャッシュルールでキャッシュ対象としたとしても、実質的にはキャッシュの有効期限がゼロとなり、すべてのリクエストでオリジンサーバーへの再検証が発生していたのだ。

このキャッシュの問題を最終的に解決するために、CDN-Cache-ControlというHTTPヘッダを利用した。Cloudflareは、標準的なCache-ControlヘッダよりもこのCDN-Cache-Controlヘッダを優先して処理する特性がある。具体的には、/vi/*と/en/*のHTMLファイルに対して、オリジンサーバーからCDN-Cache-Control: max-age=86400(86400秒は1日を意味する)というヘッダを返すように設定した。これにより、CloudflareのエッジサーバーではHTMLファイルを1日間キャッシュするようになる。一方、ブラウザには引き続きcache-control: public, max-age=0, must-revalidateというヘッダが渡されるため、ユーザーのブラウザ側ではHTMLファイルが即座に期限切れとなり、常に最新のコンテンツを確認しようとする。この工夫により、ユーザー体験を損なわずに、Cloudflareのエッジサーバーでのキャッシュを有効化し、ウェブサイトの高速化を実現できた。 また、新しいゲームのバージョンをデプロイ(公開)する際には、/vi/と/en/のキャッシュをCloudflareのエッジサーバーから強制的に削除(パージ)する手順を組み込むことで、最新のコンテンツがすぐにユーザーに表示されるようにしている。

今後の改善点として、さらにウェブサイトのパフォーマンスを向上させるための計画がいくつかある。一つは、トップページの/における言語の自動リダイレクトを、Cloudflareのエッジサーバー側で処理するように変更することだ。これにより、言語ごとのリダイレクトもキャッシュできるようになり、さらに高速なアクセスが可能になる。もう一つは、ウェブサイトで使用しているフォントファイルを外部のサービスからではなく、自分たちのサーバーでホスト(セルフホスト)することだ。これにより、フォントを読み込むための余分な外部サーバーへの接続を減らし、ページの読み込み速度をさらに短縮できる。

関連コンテンツ

関連IT用語

関連ITニュース