Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deno Deploy で Web Cache API を 使えるようになったので試した知見

Deno Deploy で Web Cache API を 使えるようになったので試した知見

- Deno Deploy で Web Cache APIを使える
- Web Cache API ?
- Deno の Web Cache API 実装状況
- Deno Deploy で Web Cache API こう使う

虎の穴ラボ株式会社

October 02, 2024
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. T

    O R A N O A N A L a b 2024 Deno Deploy で Web Cache API を 使えるようになったので試した知見 2024/10/02 toranoana.deno #18 虎の穴ラボ株式会社 奥谷 一陽
  2. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    自己紹介 奥谷 一陽 所属:虎の穴ラボ株式会社 興味:Deno、TypeScript 最近買ったもの:数字であそぼ 12巻 X:@okutann88 github:Octo8080X
  3. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    アジェンダ - Deno Deploy で Web Cache APIを使える - Web Cache API ? - Deno の Web Cache API 実装状況 - Deno Deploy で Web Cache API こう使う
  4. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API を使える

  5. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API を使える

  6. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache APIを使える - Deno Deploy で Web Cache API をベータサポート - Web Standard の Cache API と同様に、 リクエスト(または文字列)とレスポンスをペアを保存するストレージを提供 - 半永久的(少なくとも30日)キャッシュする - パフォーマンスの向上に使うことが期待される - ベータ期間中は無料。それ以降はDeno KVの費用の1/10程度が見込まれる
  7. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache APIを使える 告知では、以下のような使い方が紹介されている。
  8. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Web Cache API ? - Web Cache APIは、Web standard のAPI - サービスワーカーで仕様定義されているが、サービスワーカーで使うことを強 制しない
  9. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno の Web Cache API 実装状況 
 

  10. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno の Web Cache API 実装状況 - Deno で実装のある Web Cache APIは3メソッド。 - put - match - delete
  11. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno の Web Cache API 実装状況 - Deno で実装のあるWeb Cache APIには、ないものがある。 https://developer.mozilla.org/ja/docs/Web/API/Cache
  12. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno の Web Cache API 実装状況 4メソッド無い - add - addAll - keys - matchAll 確認してから使うと、後から困ることを避けられる。 しかし、現在の実装でも使える場面は十分ある。
  13. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API 
 こう使う

  14. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API こう使う 前提 - Freshを使用し、背後の microCMS にコンテンツを保持する構成
  15. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API こう使う 方針 - Cache 全体を消すために、 Keysでキー一覧を取得はできないので、 「キャッシュ名」で丸ごとキャッシュを切り替える - 「キャッシュ名」自体はDeno KVで保持する import { getCacheVersion } from "./kvStorage.ts"; export async function getWebCache() { return await caches.open(await getCacheVersion()); // cacheName from KV }
  16. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API こう使う Deno KV で「キャッシュ名」 の発行と管理 - キャッシュキー - あれば返す - なければ発行 /// <reference lib="deno.unstable" /> import { CONSTS } from "./consts.ts"; const WEB_CACHE_VERSION = "web-cache-version" as const; async function getKvStorage() { return await Deno.openKv(); } export async function getCacheVersion() { const kvStorage = await getKvStorage(); const version = await kvStorage.get<string>([WEB_CACHE_VERSION]); if (!version.value) { console.log(`${WEB_CACHE_VERSION} not found`); const newVersion = crypto.randomUUID(); await setCacheVersion(newVersion); return newVersion; } console.log(`${WEB_CACHE_VERSION} found: ${version.value}`); return version.value; } export async function setCacheVersion(version: string) { const kvStorage = await getKvStorage(); return await kvStorage.set([WEB_CACHE_VERSION], version, { expireIn: CONSTS.microCms.contentsExpiresIn * 1000, }); }
  17. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API こう使う import { FreshContext, PageProps } from "$fresh/server.ts"; import { Pagination } from "../components/Pagination.tsx"; import { CONSTS } from "../utils/consts.ts"; import { contentDigest, getNewsList, News } from "../utils/microcms.ts"; import { getWebCache } from "../utils/webCache.ts"; export const handler = { GET: async function (req: Request, ctx: FreshContext) { console.time("GET /"); const cache = await getWebCache(); const cached = await cache.match(req.url); if (cached) { console.log(`cache hit ${req.url}`); console.timeEnd("GET /"); return cached; } console.log(`cache miss ${req.url}`); const page = Number(ctx.url.searchParams.get("page")) || 1; const newsListRes = await getNewsList(page); if (!newsListRes.status) { return ctx.renderNotFound({}); } const res = await ctx.render({ newsList: newsListRes.contents, currentPage: page, totalCount: newsListRes.totalCount, }); res.headers.set( "Expires", new Date(Date.now() + CONSTS.microCms.contentsExpiresIn * 1000) .toUTCString(), ); await cache.put(req.url, res.clone()); console.timeEnd("GET /"); return res; }, }; キャッシュの引き当て レンダリング結果を キャッシュに設定
  18. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    Deno Deploy で Web Cache API こう使う // import 省略 export const handler = { GET: async function (req: Request, _ctx: FreshContext) { const cache = await getWebCache(); const cached = await cache.match(req.url); if (cached) { console.log(`cache hit ${req.url}`); return cached; } console.log(`cache miss ${req.url}`); // 本来のURLに戻して、リソースを取得 const res = await fetch( resourceDomainConvertBack(new URL(req.url).pathname), ); const blob = await res.blob(); const newResponse = new Response(blob, { headers: { ...res.headers, "Expires": new Date(Date.now()      + CONSTS.microCms.contentsExpiresIn * 1000).toUTCString(), }, }); await cache.put(req.url, newResponse.clone()); return newResponse; }, }; micro CMSに置いた画像は、 リクエスト結果を そのままキャッシュする 結果をそのままキャッシュ
  19. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    動作確認 https://xocto8080x-fresh-micro.deno.dev/
  20. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    パフォーマンスは上がったのか? - 未キャッシュ:600ms程度 - キャッシュ済:2~300ms程度(ローカル実行では10ms以下) => パフォーマンスは上がった
  21. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    キャッシュの有効期限 Deno.landのブログ記事によると - Cache-Controlヘッダー - Expires ヘッダー により有効期限が設定ができるとあるが、 「有効期限が来ても残っている」 ような挙動に見える const res = await ctx.render({ newsList: newsListRes.contents, currentPage: page, totalCount: newsListRes.totalCount, }); res.headers.set( "Expires", new Date(Date.now() + CONSTS.microCms.contentsExpiresIn * 1000) .toUTCString(), ); await cache.put(req.url, res.clone()); return res; }, };
  22. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    キャッシュの有効期限 Deno.landのブログ記事によると - Cache-Controlヘッダー - Expires ヘッダー により有効期限が設定ができるとあるが、 「有効期限が来ても残っている」 ような挙動に見える Issue出したら、 「need investigation」(要調査) になったので、回答を待ちます。 https://github.com/denoland/deno/issues/25795
  23. Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024

    まとめ - Deno Deployで Web Cache APIが使える - Web Cache API は リクエスト(および文字列)とレスポンスのペアを保存する - Deno には Web Cache APIの中で実装がないメソッドがある。 - 代替として、Deno KVで管理し、「キャッシュごと切り替える」戦略が取れる - 今回のケースでは、microCMS自体のレスポンスが十分早いので 感じにくい面はあるが、パフォーマンスは上がっている - より遅い、より容量の大きいものがレスポンスに関わる場合 より効果的であることが想像できる - 有効期限周りの挙動は、気をつけて検証する