8月28日、DenoはWeb Cache APIのベータサポートをDeno Deployで公開した。このAPIは、ウェブ標準のCache APIに類似した機能を提供し、Request/Responseペアのキャッシュを可能にすることで、ネットワークリクエストの高速な応答を実現する。
Deno Deployは、エッジコンピューティングを利用し、ユーザーに近い場所でコードをホストすることで、遅延を最小限に抑えるサービスである。今回のWeb Cache APIのサポートにより、開発者はさらなるパフォーマンスの向上を図ることができる。
Web Cache APIとは?
Web Cache APIは、ウェブブラウザやエッジサーバー上で、HTTPリクエストとその対応するレスポンスをキャッシュするためのインターフェースを提供するAPIである。このAPIを使用すると、ネットワークリクエストに対して、素早くレスポンスを提供するために、ローカルにデータを保存しておくことが可能になる。
Web Cache APIの主な特徴
リクエストとレスポンスのペアをキャッシュする
- Web Cache APIは、HTTPリクエストとそれに対応するレスポンスをペアとしてキャッシュすることができる。これにより、ネットワークからのリクエストが再度行われる際に、キャッシュされたレスポンスを迅速に返すことができる。
オフラインアクセスのサポート
- キャッシュされたデータを使用することで、ネットワークがオフラインのときでも、ユーザーにコンテンツを提供することが可能になる。これにより、ウェブアプリケーションのレジリエンスが向上する。
柔軟なキャッシュポリシー
- 開発者は、キャッシュされたデータの有効期限やキャッシュ制御を細かく設定することができる。例えば、
Cache-Control
やExpires
ヘッダーを使って、データがキャッシュ内にどのくらいの期間保持されるかを指定できる。
- 開発者は、キャッシュされたデータの有効期限やキャッシュ制御を細かく設定することができる。例えば、
標準的なブラウザAPIとしての提供
- Web Cache APIは、モダンブラウザの標準的なAPIの一部として提供されており、特別なセットアップやライブラリなしで使用することができる。これにより、ブラウザに限らず幅広い環境で利用可能なAPIとして設計されている。
Web Cache APIの主なメソッド
caches.open(cacheName)
:指定された名前のキャッシュストレージを開きます。存在しない場合は、新しく作成される。cache.match(request)
:指定されたリクエストに対応するキャッシュされたレスポンスを取得する。cache.put(request, response)
:リクエストとレスポンスのペアをキャッシュに保存する。cache.delete(request)
:指定されたリクエストに対応するキャッシュされたレスポンスを削除する。
使用例
以下は、Web Cache APIを使用して、リクエストに対するレスポンスをキャッシュし、その後のリクエストにキャッシュされたレスポンスを返す例である。
// キャッシュを開く
const cache = await caches.open("my-cache");
// リクエストをキャッシュから取得
const cachedResponse = await cache.match(request);
// キャッシュされたレスポンスがあれば返す
if (cachedResponse) {
return cachedResponse;
}
// キャッシュがない場合、リクエストをネットワークに送信
const response = await fetch(request);
// レスポンスをキャッシュに保存
await cache.put(request, response.clone());
// ネットワークから取得したレスポンスを返す
return response;
利用シーン
Web Cache APIは、頻繁にアクセスされるリソース(画像、スタイルシート、スクリプトなど)をキャッシュし、ウェブアプリケーションのパフォーマンスを向上させるために利用される。また、オフライン対応アプリケーション(プログレッシブウェブアプリ、PWA)の開発においても重要な役割を果たす。
このAPIを使うことで、ウェブアプリケーションのパフォーマンスとユーザーエクスペリエンスを大幅に改善することができる。
競合との比較
Web Cache APIに対応しているCDNエッジサーバーは、現時点では多くない。Deno Deployは、この機能をサポートしている数少ないプラットフォームの一つとなった。しかし、他にもいくつかのCDNエッジサーバーが、類似のキャッシュ機能やAPIを提供している。以下にその一例を挙げる。
Cloudflare Workers
Cloudflare Workersは、エッジでのコード実行環境を提供し、標準的なCache APIもサポートしている。これにより、リクエストをエッジでキャッシュし、パフォーマンスを最適化することができる。Fastly Compute@Edge
FastlyのCompute@Edgeも、エッジコンピューティングとキャッシュ機能を提供している。独自のキャッシュAPIを持ち、リクエストの高速処理やカスタマイズされたキャッシュポリシーを設定することが可能。
- Vercel Edge Functions
Vercelは、エッジでの関数実行をサポートしており、キャッシュ機能も統合されている。これにより、パフォーマンスを最適化し、ユーザーに近い場所でリクエストを処理することができる。
これらのプラットフォームは、Deno Deployと同様に、エッジでのキャッシュ機能を提供しているが、Web Cache APIそのものをサポートしているかどうかはプラットフォームによって異なる。
Deno DeployにおけるCache APIの利用方法
caches.open()
メソッドを使用してキャッシュを開き、Promise
を返す。このPromise
はCache
オブジェクトで解決される。
const cache = await caches.open("my-cache");
キャッシュからデータを取得するには、cache.match()
メソッドを使用し、Request
オブジェクトを引数として渡す。
const cachedResponse = await cache.match(request);
- 新しいRequest/Responseオブジェクトペアをキャッシュに追加するには、
cache.put()
メソッドを使用する。
await cache.put(req, res);
実際のWebサーバーは次のように構築できる。
const cache = await caches.open("my-cache");
Deno.serve(async (req) => {
const cached = await cache.match(req);
if (cached) {
return cached;
}
const res = new Response("cached at " + new Date().toISOString());
await cache.put(req, res.clone());
return res;
});
キャッシュポリシー
デフォルトでは、キャッシュされたデータは無期限に保持されるが、標準のHTTPヘッダーExpires
やCache-Control
を使用して、オブジェクトの有効期限をカスタマイズできる。
const res = new Response("hello cache", {
headers: {
"Expires": new Date(Date.now() + 3600 * 1000).toUTCString(),
},
});
await cache.put(req, res.clone());
パフォーマンスと価格
Deno DeployのキャッシュAPIは、512KBの「ページ」単位でデータを管理するマルチティアのLSMストレージエンジンを利用している。これにより、RAM、ローカルNVMe SSD、クラウドオブジェクトストア(例: S3、GCS)など、複数の場所にデータを格納できる。
Web Cache APIのベータ期間中は、Deno Deployのすべてのユーザーに無料で提供される。
詳細はIntroducing Web Cache API support on Deno Deployを参照していただきたい。