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 こう使う

Avatar for 虎の穴ラボ株式会社

虎の穴ラボ株式会社

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自体のレスポンスが十分早いので 感じにくい面はあるが、パフォーマンスは上がっている - より遅い、より容量の大きいものがレスポンスに関わる場合 より効果的であることが想像できる - 有効期限周りの挙動は、気をつけて検証する